From a56838167c0aa891afc5c8152ec1f988c0e92f0d Mon Sep 17 00:00:00 2001 From: mathetake Date: Fri, 4 Sep 2020 15:25:33 +0900 Subject: [PATCH 1/2] update tinygo version, fix ABI aligned with wasm:1.15.0(wip) --- README.md | 8 +-- examples/README.md | 23 ++++++-- examples/helloworld/README.md | 8 --- examples/helloworld/docker-compose.yml | 12 ----- examples/helloworld/envoy.yaml | 6 +-- examples/helloworld/wasm.wasm | Bin 45868 -> 0 bytes examples/http_auth_random/README.md | 10 +--- examples/http_auth_random/docker-compose.yml | 12 ----- examples/http_auth_random/envoy.yaml | 6 +-- examples/http_auth_random/main.go | 2 +- examples/http_auth_random/wasm.wasm | Bin 83259 -> 0 bytes examples/http_headers/README.md | 8 --- examples/http_headers/docker-compose.yml | 12 ----- examples/http_headers/envoy.yaml | 6 +-- examples/http_headers/wasm.wasm | Bin 48284 -> 0 bytes go.mod | 3 ++ runtime/abi.go | 2 +- runtime/abi_alloc.go | 2 +- runtime/abi_configuration.go | 4 +- runtime/abi_hostcalls.go | 52 +++++++++---------- runtime/abi_l4.go | 10 ++-- runtime/abi_l7.go | 22 ++++---- runtime/abi_lifecycle.go | 8 +-- runtime/abi_queue.go | 2 +- runtime/abi_timers.go | 2 +- runtime/context.go | 8 +-- 26 files changed, 91 insertions(+), 137 deletions(-) delete mode 100644 examples/helloworld/docker-compose.yml delete mode 100755 examples/helloworld/wasm.wasm delete mode 100644 examples/http_auth_random/docker-compose.yml delete mode 100755 examples/http_auth_random/wasm.wasm delete mode 100644 examples/http_headers/docker-compose.yml delete mode 100755 examples/http_headers/wasm.wasm create mode 100644 go.mod diff --git a/README.md b/README.md index fe4e2aa1..006aa537 100644 --- a/README.md +++ b/README.md @@ -12,13 +12,7 @@ Any comments, questions, issues reports and PRs are welcome. Please open issues/PRs or reach me [@mathetake](https://twitter.com/mathetake). ## TODOs -- docs -- support get/set shared queue -- support get/set shared data -- support get/set property -- support metrics -- support gRPC -- enhance error handling + ## references diff --git a/examples/README.md b/examples/README.md index 1cc84a0b..4e2be86d 100644 --- a/examples/README.md +++ b/examples/README.md @@ -1,7 +1,24 @@ Theses are the proxy-wasm-go reimplementation of examples in https://github.com/proxy-wasm/proxy-wasm-rust-sdk/tree/master/examples. -Before you try an example, you must install tinygo(0.12.0 or above) for compiling your programs to wasm binary. -Please follow the official instruction [here](https://tinygo.org/getting-started/macos/). +## requirements -Currently they are tested against `docker.io/istio/proxyv2:1.5.0` image \ No newline at end of file +- TinyGo(0.14.0+): https://tinygo.org/ +- GetEnvoy: https://www.getenvoy.io/install/ + +To download compatible envoyproxy, run +```bash +getenvoy fetch wasm:1.15 +``` + +## build + +```bash +tinygo build -o ./${example}/wasm.wasm -wasm-abi=generic -target wasm ./${example}/main.go +``` + +## run + +```bash +getenvoy run wasm:1.15 -- -c ./${example}/envoy.yaml +``` diff --git a/examples/helloworld/README.md b/examples/helloworld/README.md index 6ed198f2..561ccc47 100644 --- a/examples/helloworld/README.md +++ b/examples/helloworld/README.md @@ -3,14 +3,6 @@ this example handles http request/response headers events and log all headers. -### build && run -``` -tinygo build -o wasm.wasm -wasm-abi=generic -target wasm ./main.go && docker-compose up | grep OnTick -``` - -now you can see something like: - - ```bash proxy_1 | [2020-03-25 09:04:56.149][1][info][wasm] [external/envoy/source/extensions/common/wasm/context.cc:1077] wasm log my_root_id: OnTick on 1, it's 1585127096149656000 proxy_1 | [2020-03-25 09:04:56.154][1][info][wasm] [external/envoy/source/extensions/common/wasm/context.cc:1077] wasm log my_root_id: OnTick on 1, it's 1585127096154901000 diff --git a/examples/helloworld/docker-compose.yml b/examples/helloworld/docker-compose.yml deleted file mode 100644 index d36a0c33..00000000 --- a/examples/helloworld/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2' -services: - proxy: - image: docker.io/istio/proxyv2:1.5.0 # TODO: replace with envoyproxy upstream - entrypoint: /usr/local/bin/envoy - command: -c /etc/envoy.yaml -l debug --service-cluster proxy - volumes: - - ./envoy.yaml:/etc/envoy.yaml - - ./wasm.wasm:/etc/envoy_filter_http_wasm_example.wasm - ports: - - "18000:80" - - "18001:8001" diff --git a/examples/helloworld/envoy.yaml b/examples/helloworld/envoy.yaml index 3ddd53fa..b2b29f32 100644 --- a/examples/helloworld/envoy.yaml +++ b/examples/helloworld/envoy.yaml @@ -3,8 +3,8 @@ static_resources: - name: main address: socket_address: - address: 0.0.0.0 - port_value: 80 + address: 127.0.0.1 + port_value: 1234 filter_chains: - filters: - name: envoy.http_connection_manager @@ -33,7 +33,7 @@ static_resources: runtime: "envoy.wasm.runtime.v8" code: local: - filename: "/etc/envoy_filter_http_wasm_example.wasm" + filename: "./helloworld/wasm.wasm" allow_precompiled: true - name: envoy.router config: {} diff --git a/examples/helloworld/wasm.wasm b/examples/helloworld/wasm.wasm deleted file mode 100755 index 1b7b63a4acf6cac534d168620c740434f34b0259..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45868 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 diff --git a/examples/http_auth_random/README.md b/examples/http_auth_random/README.md index f9721d9a..f32966e5 100644 --- a/examples/http_auth_random/README.md +++ b/examples/http_auth_random/README.md @@ -1,14 +1,6 @@ ## http_auth_random -this example authorize requests depending - on the hash values of a response from http://httpbin.org/uuid. - -### build && run -``` -tinygo build -o wasm.wasm -wasm-abi=generic -target wasm ./main.go && docker-compose up -``` - -now you can make requests authorized randomly: +this example authorize requests depending on the hash values of a response from http://httpbin.org/uuid. ```bash $ curl localhost:18000/uuid -v diff --git a/examples/http_auth_random/docker-compose.yml b/examples/http_auth_random/docker-compose.yml deleted file mode 100644 index d36a0c33..00000000 --- a/examples/http_auth_random/docker-compose.yml +++ /dev/null @@ -1,12 +0,0 @@ -version: '2' -services: - proxy: - image: docker.io/istio/proxyv2:1.5.0 # TODO: replace with envoyproxy upstream - entrypoint: /usr/local/bin/envoy - command: -c /etc/envoy.yaml -l debug --service-cluster proxy - volumes: - - ./envoy.yaml:/etc/envoy.yaml - - ./wasm.wasm:/etc/envoy_filter_http_wasm_example.wasm - ports: - - "18000:80" - - "18001:8001" diff --git a/examples/http_auth_random/envoy.yaml b/examples/http_auth_random/envoy.yaml index 50f406ce..f267e8b6 100644 --- a/examples/http_auth_random/envoy.yaml +++ b/examples/http_auth_random/envoy.yaml @@ -3,8 +3,8 @@ static_resources: - name: main address: socket_address: - address: 0.0.0.0 - port_value: 80 + address: 127.0.0.1 + port_value: 1234 filter_chains: - filters: - name: envoy.http_connection_manager @@ -33,7 +33,7 @@ static_resources: runtime: "envoy.wasm.runtime.v8" code: local: - filename: "/etc/envoy_filter_http_wasm_example.wasm" + filename: "./http_auth_random/wasm.wasm" allow_precompiled: true - name: envoy.router config: {} diff --git a/examples/http_auth_random/main.go b/examples/http_auth_random/main.go index b95a3a5c..03368de8 100644 --- a/examples/http_auth_random/main.go +++ b/examples/http_auth_random/main.go @@ -22,7 +22,7 @@ func newContext(contextID uint32) runtime.HttpContext { } // override default -func (ctx *httpHeaders) OnHttpRequestHeaders(_ int) runtime.Action { +func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) runtime.Action { hs, st := ctx.GetHttpRequestHeaders() if st != runtime.StatusOk { runtime.LogCritical("failed to get request headers") diff --git a/examples/http_auth_random/wasm.wasm b/examples/http_auth_random/wasm.wasm deleted file mode 100755 index 891f7e43c9b5d1172059400d16626f4f23fee814..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 83259 zcmeFa3w&Kwl|R1EIrrS$+?&TuZknWNXwSV(OZrOlPFf1&londv@+?DZNYk`UnkH!; z1+*`q$U`1gaKr(j2qT~{g9<(X6%ia5bi@%66^AlEKvYyj8SypzzTdU?x%cGJ0?zpV z&+qs7rQK)0)?Rz4Cl2q?H%C_^bJr3{23UVsRu9opLkgz7wN2iz`oUNpdI|JaHZp5Han+c`EcGTODi zzbCeFL+AO!y`w$Kc6tW3=MN1JUT|S&|KKL&Fg`=aM|ws(dp2(D=^pLf-qYDVI566C z!KjK5qDn(-0>tK?t_?lIom;zxI)}P?hetGuVhyl)babe*yQ{xnxhz(mE4F?Nn1?&p zUpU$`qN1Tp*3&yM*3&uMvu&(rWK`ubb9zA1zy{C>jL04t8XOquQ8DMe>+&O!NIViz z{Ffhb9LGvH1%-(s$0~{|m7lMQBgN>C0#)ER@wlCzEG{mNmlT)g=O?TJlqpbv$S)8u zC!q?8iz7}!yuc|?PC-G$wT3Lqave)0qetiOw){PNB8lC~f9@LbUb$Ah13LDij=iX3 z2GW4+i6!#ha5K@ZJzEEdFSJ!jXD9k)t8l2Zdvp-oi$%ABU4z}~#ERiDaAIpu9r~<$ z%Q2g~dIwG)?HV3+tY{~ahDX)miB7VAsB?YSNRMMz2L(olQJ`nTas7kqyZT2?>>1cJ zy4i8Osk4{&j-v1C8rmD3$c(8$bhU02EFat2qdLlTXABN>qKBlXx;9*>jxWq6kM?$N zQ72UBc-Q*g&h0(JBfWsH?`-I-S0|NbA<^3#dpC^@_o$N%IG~KEb#@Q;bU{W>F~WqL z4L$umNI5lE)rP@=9`&A?%o{u(;*BEU=itBq#g@4G2O%S;S7vJrfo zXXl2I!OqQH0~`8#oM;?TaI~{$V1tua*x9*B~XC8-Lv=LPx()& zEg7pu!k)EUwb?7Qw+x=!W;gq))_(4qy?a#J_LXP(^?j{6?pdDQYS-Hxc8Am9spOS{ zZg*eC@u#0qX!((Jgn9huIYm_}s;p>KKj51`$Blv>-%3Xc+=Oq#izI;SgT$3~eU)}l z<-@8k9fiNFFP#Uky)PYO3DoL%?#YD_q{aF?P#P?e5 zh!=r6+Pg;~)6aO3kicVC6X{}vjn!~V{DQdMlfT93{ zE9DiLky6;_@9qOn3%6{`#MzLdF9!0+woGzHrnuE!h9s%g|Mec!?I9I^X z0vPgI215hV2;Ym45(!$q%fiq_qz(vtj7TdxA|3y=kd88if14|u)`g!63TJX@)-_4W*NIoesb` zo=w%_`fpj=(zb7 zv8_gqopuYN36h)q6cMrs82g#1Z<}sJUKB>XvaJMKhz7D1t`}WdXeUtW(^3jeEEymvoyZ6g4|wdIThRfW}}$7ZOja z?qndu{IY-yp5?a zup-RK{iCHBvt!DR=!YEvF*ah3n`cL3+QiID_(@or(FAQ&+MNYrclt4S4w|LSKQqBW zV<$gCW=~XA(747>!NkyC%pqe8*Gxo4Sfl{s!GZw+N!Ip&L;~Z$@{eS)LZ6Z`tAry? zEn;Xr4O&8Ts<6Olu)NP$x0Wxn0;WvK6lhv6fqCmcN4<~UmTb)EFm4e|n)XnnLkf3X zEBZu7z7m>B*s~ync8>&Ye+IRr?eF6ZjZB!kb}$Vc409xLcFvMbZpqk&ZCB&;$ReFbPgJWic5v)QmKG=@Zp@*kD~QV|UPTkTv`4^I?6u4!OPHfwL8 z7QUK^!sm^bJa86hg9}TgnK4fmQS+K0gp&ATz zP+ZN4Y^j2E84OQtSF^#|5E8SxlB$vY65j-PTTPhXF)K zL`;Pd_CV4TuLdJuIs(Ll!?}*Y+89~6j)+hfS7JTuELCOjFj|2EAO%53NN1ocuuRsS zv5k{DO%hD!5DCoIkuVEoyhphHF(W@ukNkfOu`oOI*~dUEU0UVYoJj2Xn5gqWCI}0x zW~4Y5+c)5Ogql5XGpSvhel-M`8H`eYL=e=~D2<7Yh3BxhO0&!^;Dhr(MHL z*Z)?q1am3iwH`hDZVRRhg!MW2j6ZGsZyNtm<3D8l`{4U9>Tjoya%-fR)2_V^?XAjn z4@@Ee?zgf71@=*^y&t8?&4ut>(e8IL#l^^O6_VI{^+-WqgHXd%ku+>7=*M z0}`R&#C-RZLK_SO$F$(M{tcEHgRcJ^g1dbWC7sbN+aY#w1h#L>h?KhivoPOuklnox zZSS(7k5Im_?vL+7hS3N;v;5_3UcntC%9 z?7G=G3-YbW$}y{rIa+hG6l0jBxH>M=(+_5-@sm{&O$|*}*aP95#>on!Oixx3fK+OM zv^&5C2(8hPBYhbxaVVj#(UFc{J!zWpFyoS+*;V@ILpm}$&16wep7^LLsWLFg45?YY z=tUo#IP=wT>j82^CrpEdqd#(&)S4;%lB#;3v}9_mN> z`{8rohD;HyVr5htEulM9G;9IDp*}eLK^TpZ8?2y%1E1ZToeT&2GI@TK9i3N{XDj?! z4$OD0Zi3BUqhg>df;ka#M{D@Q7w^^9FwBbFoG2XebOS1Z>LwX`+FHb1XM;A_yU?hB z(Uvd5)jF)G&nvx{2ldD%?8j)HK*sGkGSZrihXb(-8Rfcq=xqN!sh(2}W>hL#Qz-^L zH9Hs96sdNMjL1o(j=S7OQyGO5F+!(RmSzXLrvt!REyB>u;rCx8i5T{Qa(=~-3_;8) z_pI^(Iw&7sw(DJgk8LbJu1Tb$w8bS`^JaR14HwFh4arPQD96rkNXMQE^0eZ^+$jS! zR7~&n+v7+wb3~wmO}~do3d{~5{^I1Gc_`O28Qn9lP0=%yLoZLye=&OK5$*to2;ajb z>U8i!tL$)tHRS}s3@3A9UN9%-VM#jWv^Z5WDa_!!)?wp0@A{MHzgLAGGyhFN&(u|5 z`!~`L<{z}8$F=G|1CMKQG0o2Dm13KoA6y7bo0_FO53!#yIFE2ZU?llC0^W#ktnM*?bkoXn$FLqnI zjCuRlU$ap%^*>5Qb~4<>$xzHSx5%|@2WRqcx9k#w!ty^F(vNRDAHwc!KGb|TaXQRS zVAkDw7e+{)Fv(*5RId&($sQc(J5I96$ax~XC6q-!L5)N`tK~1#P4^sJfk5FksJ~2s92_Z{ z*7O%@rGq2I==kq%K9t;Fj?~i=)L)|H7Uo8ghwVN{zn=H0*JO(-WELd|?8{-D(}8hh zoeX7!q0tS$OCLX>Eo$_BoT2d zhilF6%f@^po8|vV5?qr&b?H}*`junJ2Z*?!hzZG2KN%zxBEjSp2x81w8F%^aGl6`O zX8Llh%Xg+-tkaTT79?_C2Pc-v2PGOO&bQujf_Oer>Z}-oKxoS4G2<&zCW_!!9!!2w zB0$ZBvWY>ZSlGejWhA}1S!?<}&%k4`u0j0+(pcLx7E=|_#ITtu%kF$XD44Ioz1Wn+ zcz%T0gpYuaJX57guZD*XsMKCkCzheJa7bXwzA(iI=L)&V!f*s96E-BCdM}_wY0mgd zO`{A${CPUg?RSWxkxCy6Jw5LvN_qAwW5ACa&@C_@e04MybE6cKr+LVO;z}O{Z}Fqs zVK)EnTBP>*L$Y-zC!+-M>@7H4Z`B9V8XjFE2c`Z?HTr0-%7x{blbopuZ7vY``pM~^v29~*O+!|cu-z+21? zCpgCy%JDkS%Q;3t1nMOLU^?4tfI)z6a=7|jOQF!QndIRFPEOYoiN)Y1>Q;X4+}!*zJ z_wC)gNBQM?Sb69Y9ZCkr;mwoD!F7i$`8bk-!uC*|A!is8l30mCW^ILYpRAhZFe}jG zD+ZQ~V}sauGJ=fpWhMUA5-9?t+!8?@i&R1KGgKouLr2qKO)XM|lH7;2IZkGP0HV7{ z70E4#ex9vkxI)BMVrG%MBN1@O!B!Ec9;ZW#g&(6Z02DS4TN8mOph>6$74~~hA2Cbi zpJnBuj=4#oM*}H|K_s#FiKB1cmx|%qqsS0ti5DxfHv|%Aa9j7W2VcMZ0yaT!+OyAS z=aQ^oR5=`DporC~5&ybN_Qd*GLWUkudZFFjVawg^TL8z68Beaph#-hHiUR;_Jn=zH zP_!Ba83p2G*q{)$WO-js?zCYKh%pPB08z4x!wcNv;vgqEzp+rKaBp(ofQ~8q#+lGJ zFsRu#&PsBa_j+*E$0NP0&Ge0<`v#yi3_O=TgN77x#^5kR2W9g5y~xyEgpCZy1>mCn z*w_zX3X}KgZp4fkVQGC=(S$40_SnSn~5^46Jxw;BiFivn3%p69=0+p+hku()l=T zVqeA)##yDlTq)v+Hv}N%NJ2MD)!0VnxN~(c=J$J1_E5Ue%V(!aav}OnrxxMjlG~Rl z277VKIIc&i9{b7gs4NOPP5PJvGRiK-=5;!sgR;OYhG6FpXYyyH3lKtWGq7u)@QN6a z`&SqVA_m}29_Y*G;K}zUuqZ|rDLwYNkr)FmOIo6(3m9d{8DaAZIKm6O7}X;>FLW-E z?9+XnlZEe4@#XYqb~&nLAu>T0!1WwDIki@xT!oZ$L}Xw>@0sh@A{9K;=Ke9-6K+wI z$+}UQJkzYG3@I5(;r4-s>?t$$KsW+&t6wk5dnNnDfGZ8|mHaX4*t@MA1wlixVz4wL zC>(5or@ElHwS4Z^s?t*{l={ri9Sjr~XM&*Xr*3o$gaMQ)QKqF-Ql zPnizA zsEqpq%Fj>Ra1KWVkiuF3Qiq}wKN&Z2t%Ecj84hMR5D_218eKYiI3sf~R{BV0SJxjq z1FQf_8dX?2kO$#r{AcI}7k3u2)34rHaF#pRS(q^W%5@XHc#|2pR+NveSN&)JLbC3M zZO5vyKIGC<4(`CB>;!=3V~&-rL45}5_}P_UumkFF-I*;7WY}3b@WH)%ls^-*j4Wm! zVb>rBvppnBCOdGcNAc|$=(&&5esG~ z-hhf~nfIa;*9)|FImSI@1Xq8c@UWOSaa@0rbXBsIk^=##>8K-a^#P2;g{}kK9^bbrYfR0ERcSjw_^DZ#f;HJ9#p$PGE`2?GU^z z!|6q@a{z%0#*37q1&r+ng}dNEPwf}31>LM;hwA2IVS~IT!?8NB6+tg=bVYeGBk3O2k|<~OD6wLxCKnL zcE91&A~lpQW5VY2G}Z)Y;aCc)U|?2n*9xSJpi!UcqMijAR`$TddB{!K;|OuT_JuA%y7KW^c~^evoN za0@4bRZ!H&jf(8`7pN1|;6DtiBxw0H`Xp!n6lZ3#SHWBT7T!(?^!K=$_2qt9AaQD< zRg&~#+~1GNYo5{_;Ns0Wo}ZZI`Kg-ctAyv+dJR~vfraJE4$ks+&GL>g%Wasu7Krc< zGEie#%^)fchVhB=5nR4-24s_wI!lWEVis zaFf)m@@R9oW_pq9S-4)rSq4{EeXPrBJS;1?#>Ax}ZU9j02abN}leD0(} zZftn~(-*dI^8z7mQ7;sIE^8~fAj@r7Ma48C7@9~D4hj}JObUY~9L07V84idRpP{PtCMWoIRt|3V^D?GqGe2spi&D1 z?+bdUNqY>#q!Pda`GiW|46RCVBO_Z2rKAQZ(8B86(9&F_Ae&~Bi(ob(_FcOdBOgp6 zS3y;o-2s9iA$te9Ilva&Drs<)}jQnV(0{^r7XLmvWPq zw3lym1ud`8Er03*2XFb_(6GY6M6Tu5xZPE0a+U%Tqohl*&c$nb(lBsUf4%^XM<2?@ zW|-<=fh>FGU(<3K$S1zf@Q42+h0n)jowpIcIl2>GJ5(pcbMxMQEUR)O4{X|V0C%7< zj;O?7yNQoG$KqqHBmN%aU!bEy+S{zX^R%}{d#7q|mG(Nc2bE^@C%syF8O$8EszZ{rfgaHb11$v3;TH3HRdUD7KeW4 zUPhDPFm{BTCP15b7IaFaL=+=y=V3IrwCOKa*2Os2OiT=I92chVE)xtIvSeaq3fE%m+O;kOIR8X&wrJS=j~# zg@j0a_JI}YGP)vvPpDm?UXYfVUXWM8sliQ0xVetF3T>ng&-Mh*7_wYPA7r`Ci6Cf+ z<~lZJZ66;K$Qs~=Z&+dG-(SnUU8jUwDXby*l0Q}SFUtbopd zdEC0PeSWS5+`E1v$EW5uI{~-Cb0rMFpVn!Cm@!|3j9U`6k5_R0h|#HL+;Dwnf(L@2 zr5hPA8q>xhIql?DD7IX_4{rP$j(_u=avZC_iM_?Qf{m0Pg5%I8P%6e~;3`kgW{HPG z7eZ;JTEQ$#D{k^@wPKWDMjdCA*g$@;sacEqJD!@Mq}UD%85g+%v9LJnk)x-FzgT=c?Eo2w_12_IOv&-9!C#PrGLbn zK%=$V%vCm?tO@1_hL7pNe{gd17!1g42WkUStSN5&LluOUXu8XCZ%|>dP=H1MXPM7K z0WiP7?l4T{G2BE`N@-IHFWf^404+u&_HJoH;`kx?uelzB)s!8+xn=^r^w>D$0Yj%? z%faD8w{JlRyTr?OfM*PXDLa7kml%ZapcRLP#qvqFctUpt)}wDFk_rtDtxXaW>|ooB zKpF?{as`l`S3Et{{!d>4OfWykop#hfh9D%NwGRc1-y{mu7`9}%0&sE)12XPGmeBdS z<-B$PMc_mfR?ojTY?3kR$uA-3z-!-Zhg= z8%Uju<2;YMFE~WY&8=AJkrT+_1@>%Nz2l;%K5Y3UMfU>63#n+C7hUc=d`)3U$lG;$)UN9#C1pAErZS&v=PxE4*EiYM$4XAUmYmHo(ggPpA za4rh5I0M=6PSthz)E;OI(QB;9ODSyJDMkEtVym^!kW&Z5VIXnnGmEPT6T})rg4ipE zX22yP%Ur2If+b5TA~}_|IF@=GIVZwH;T5#B`KFjbghMq6nzsA*UbPn+Gc%I^M3Ryp zkbwbuq5lGl4eyj`?ITOyu$8LUS#pYCg0xZ@G#C7Eu%|;z0_8v)*^ON^G;r_kyxBTp8b7? z*o?gUf3_9<1IiaQOt4s(xb8W)RjfCPCN3@x4u2>sdX{G7f!y?#-PPrO>f2e-xmFw+ z778jUum`cC6Mq+VUA~6{mp!}kLTeu?ek^);LosA7*%+U^GZbi5C?_m>s0V|8G85TQ zil8r}{Qt$b1t2)_RZvGzfOzM@{{}u90Ta{Tb1C!+G$OvM=kR(b7r_44f-N`E^AWtR z12a?I10(ZmxQ6O<;4pa4^*?{kIRhWegH^(BfSQy&nf&E@UcLUd9lN~fjyuv06}8sS z{sp{7?_g(Q09V7Hp!+fj+#JCv%?X8EBF2$}TV){5;mgVeIB7ox8Tjf)U#1XB+bb}% zLY?ynHvy_Z4q*y`R=30C@dcwazJY1Jm&?jf6+WQA%J@#HH7YMeOC3?EgEdURlAn(9 zVpCSx;akLe4YP1-85iu5W+xgp9In7XkD|fSShjL?sI~YC7%Ili%89K^2nARHu$2X9 z(}ZS#KWrkt4T>5j(l?=%x)QP&Jj5C8a3(I;v3k|m=QbF7lx2=GW(u&Da$9IJ>H7v(l#4+XY0s^%zs2S-X1+Wucy zP-^}9KW0H$s}=8_EB4Zu8MhA`46~mX=DxQ4+Bn-D2Gc9hbu^p~82?%0KV|&KjsLLm zzi9k>jen={_Z$CRtOp?O_)dSDvl%MQf#DOZ326Tz4Jp`Q4Fp=Uv%DYD)`KzO?T+9d zbf+u~@O&6=IOW!xz*cK_a0k5BUNLTI4;z@vOm2en3Xg2`YLihcFXCYo%YJ<5#Tb>? zS=As1q(n9<=AwTf$mOaav`*10k?gVs7GyXVy|)%|c<0$2(t6-Q0+1&!p=RJmJr!8R zmlk6BV1z3WH0V5jyNmqd!pH==q z6dX3WZR4GemTRz4iLA&cyR)R#Xz8y zPRO(&FEtdd#Eizpat8O9`Z6V6ay7cU#B)xNUdM@5KGJao2+Nx-MhgRFt=+D_T#XM( zb56vEF#3ojiu+r5l`lz5(J-c3dl|ku%@qU?CUJoZ2$KQAVj`^9@3<(wwt#3edktS+ z2dEB3`n;5c^cSPedwra#aQm*19$StZ>f8sxXS7@)MNg{i6#14Z@u6wh((oWa1$gKV zCgLb@L{Vq(s$F)%wS6ok^=5@$kdou*9}&8HW!gDRuPjiJqkH~go;mbUdqDW;bubSc zxDTDeg)Q!I;qI8t>twhLhcO91pPi)VbbaRvrpmGC2vp?aI-(d@B5T;L5?*Mwg8?PN zE9nAepwsBl{wk1;!H2lHszxf;*to;G0v>R5pk|n0-;ze~Qc^*%WP-`ZeyHT5+W)Zt z*x5|*5$SqSh0ZJtGB7tYqrj{?O)oiI2J2rF;QE*M+_THb$H7{ZsLif_7viNdk$4Xo zFm15p%L3!3Ac4J%G#{ZFzL&(|VN}G67;w)Et$E2uW$5zDpJ--*54#M*TKU+$LSH}i z0d@uz$XjQvPF5mM=adM(dkX>aAD-gCFfeX{$?i`vt30^0HvXpt zaG5_4R%bc*vFBdwYT?sYf#C9OKQQES*n3RcWBdzrbVz%fwRfKO)@To^lqFVa585o) z+;Y)q{!l>BZhW>|Z#c*(3_hCL0T^sPVVl)qXTkKBkHcf6IGjuP+J}Bi4Wldf69AEP zGMM#bG+_ec4MyxL9m|14iNRZA94#=9xCJO4^d`p&RAxRjNh}yQQ0M%Py@C=f>O+Pe zPz8N{oC6piPv&^ey%h+>29e|E_fUv>6W__iJAkYrhMT6)=3pMh8kZ>bEtI$*_Z|Lp zLL7I`9-}}42IDfgfP)gC->nqTFGJ_d6LQVR~W%L{HiSs-H*s2%9y#9HF-MqlY4m>{oU zlL)UK7hdTfoS24mm>=nK_^?OP74UJ=oUU{_fD4mbKH0_=M5&tjJ`%rQ4xzHZvYb$* zGSWrZ%t!Y77_CS3y^m0Gdg~ z%r_#AD8RftO1dmzlbo500fyHj6Wo{73t6;Hv$c@3C0?OK6o&^95AgV+DdAaY5`1=P z8qA9rz!ykmQN`Zp;3XY!YN8=2_!4s7VTz#AMBe8XJ>n|hXw z!*~>a+VJGDtvL+ia+i7|z3=M@NLfBO*ni9*slDLX{=u$MsW4mLNPlm4&lL3;x&ki; zKRVnyuxW|{t4Z?e0gYZwpeNh@v%31nzyOe6J1@XZ|83w;9qa|8him7Vz_K%rIuj{F zT?4({O9MXX-fuK`d+>{#JpVb`m-~ikW26joy#|9SZ2!Bpg`kI&xCFWNoy`JIW!QrJ|u1?M7aEIpd7^-h*Y-(<4 zZEIiBwZ3~p&&Exgd;7NZZygvM+BQ5gI=21%3od+LxI}$@eM5a?eN%mNeM^07eOrBd z{gQ_IhK7d5hNgz*hL(obhPHBjZKZsjV+C>jctwXjZ2#9n;M!Lo0^)M zn_8M$o7$S%o0c@!H#amlHa9glH@7smHn%mmH!o?aZ)s?0Y-ws~ZfR+0ZE0(1Z&}h> z-`ddH*xJcv(hRVnKje2^@pF)-fcZsDZzF$65@-*F&-~P84jDp+gvSqY9x8u|AJ@#`<4>Mq zn1`Aw^&Scze{%Cs`N1!0$}eM@R=gAV;1@Vq9hgcI5@n%cf*FBfpB9G&f(Yf%MYu1rpJxInCMb( zsYj7r-#dWWXrOmwbBMDM;EKUnaQXBj8H6)=%650>tFlTY$zSxOp3%*N8?2F{6;P;S z{iDa|A5qRXeF1L!kK%`dtAhel`aXYI_;TwoWDe!AO8vJ6;an_8&H1+@|30`!O_`^S zA3#Ldg3#aF#?k6C&)*nT_n()j+t9OqY*T0Nz{bHj^-7T+cnUQIDldezHma0ef&{$V zrmSwd6DR2@C35OK%NLl zCPtsZgV0Ws$vG7{OpLx_aw6p>=M3a9(S8#TQt9SP4x=_%MLdydlE!GX9FO%39A+@E zgPG{e!voE)gSV3aGX;QA_XBvaP+lw&I|lxKxQL3K1@A5f@pIV6!RMc|4uQOgJqqtp zxadMb!zfE%4&RjC7X%~9z7ApOpxFY=s7=h0RwHSQ+F!w=$_A>nlE$d;_1nyR4i9|M zLdB{jlTo(=@nSf4H6DLL3W@jyeBq0V{Re_V4~Uos5Gg-P$}?&o9;9huVAQS)(&h^s zqxSM3ZLy>=8b3WqJ77s70_H{Dz%}grC9{o-6r`=JE@ay$}ic z81{wlmwZNZ`Nhg^N5VYjUnTjB=JKP;UJ>M9FZqnxr{Y1H3x_3*QG0EW)+=d@+M9#4 zn@s=?J3?Q zFq1G)C=*@JPGh>zR_qXbz97?0+(4lE0LEM(yvIGRgmtG)COdjiNBoyd6n3jySbI+5}C*Mh_|bRy&NCxgWI>O{ul-wP5q>O{ul&j*P^ zI+5}CPlLn@bRy&N-vo&l>qN%me-09_)QODSd0^U)Fm;z6ElgrGC%KNYOOZe}l&+9` zM(xA!V40MjY#Fs{gS4Xrj#0Y_k2aVaWveBP(Zn%`i#965{EmdYn7slXwg0p-0b|te z#Dhw(yhG9$wTJQe0E(CEfyZd#!vVUaa&JWV!${1tt=LuYyG1R>t_^~gvOkUR69B6y z7PO2y58+{3@vp&qiCGIYcNi}|fJZ?j_7uD#SbUgbpG8onsz~g)AQ)4T3fhDCbDl<` z8;QRRuL)@t`!qJji~op+!M660*r>Ak7k6Pty^m-?nW;EoGO%v zMC^s|IGj5f?d%DffDWA3-8M zGakDiK4mPXVh(ULfsfAn zfkoP^(qnUx(vxywmAW29_dSTbu2@tw;zD2m{Skx+k({WXGHman{lv8I}Wm~f0vaQ*mnl^|qUHUE4HC)D+h;&mB z-kSqbB|k_iMbkD}rd@iorsA}K3LP(HXCaThHREM8a7QVm2QcX^*7WL&35>+UqSr<0 zZ@DgFp=oMHA)b!|#v|B`Rz<~3Bvj1jqm=+E^+{B^8&uAPPnZ6caOwf%2?r#qN)9hq z>T2lcWdNZ|-==ANE`ZZ;=+egu*wO$@qAGRxOh^^d-VYGEbiaVD4ZtL-N*+XDAyh2{*slOWmtM#va;3sU`dy-`?*>S9gzlAI@lsXsuEBE=_d3dK-0~x6=?1)=%AW)1;mdoy2?u3 z13v@s4uI0tJktyzXL2`^qZRqHI}qn6wh~d5*^I~& z$i!TuqLuN?iJ|zM#Ej}@(7P6C_?s002k7R`uxe=G(BVe8HET8kbca`2H7)SzocCH* z)iDUrId?n)1XkJFY*6}fWJPE55?Se5-)q~d2Ip1ghl(A=Z zu>3jDy9#N}t9f&tLYPwR%(V*V{1lOU89Cfa%zOip#~E2*<;}FAKVD;G$Vyg}B7(me zOW|J#wA2PpndMa+kA%$3aO&oCMV*FDomz{z3y>qAiO%^rY1d7bph`UtkY*%agKRqI z`W%Q3u7+qh*Z*uWfKncy8Mq6Obk0>dXbGxR**v9I0_1DRrmL;G03|9A? zV#0!@Mn>L@>oE$qqs*sKX5L(@xZ-vsRQw|!58zSV4>})10CYWsYUt+O6{1VRny$Nq zF3uVAbWljVD@Wp8n#AADSL!!F=t3#e&6^b>(S(J>Sz0*=Mjf8H5KW4)hP0KcScXW& zaeSP{$2vT!_k!Nd2!P&igI2nEYeV!(Skt>UN3RYFy=!yyt`&N#{v9~z=Cv}*DibgX ztCCevdT~@a6YZdzR~2fD2}@h5LT%CE8P9>tkE8tcY)`dSQ1L2T@jE_jpsFauqxvQw zuS6hIgU8)~rdcy@-HeK6#POG^o3GRv2(%$iH*bM7iyGAguL9Nc7Cb4?XVfY69fVE* zB;CA^k~dn!bWo`MXpS{H_@Ojmsh-r_xsX!mL^Xi&bTtd7{T}S0b1pQN1FJU?RaFWC z=$uXxVU^Wp!>Vc#!gS8aBa$cTN5ZOV71HUPi$Zx4#(Z!%7!Sr>3IJ0G&F|#igr%D;VO8}e(&^^kzqN{a)4@C)R!%X(PONGMJi7T0?aP5k7)LV% zN!D%z=U&CgpALhs`aT5aA&}XLM)uU813>NkZ^tUGL0ow^;&~;KV1}#t-;H@+LHx!b z{=Hb{1;iggoJVl;e-NvF9O!;6CI5`)0p!5$R`Y)x^QMEGUm;%1`17$$3*vL}Y%a9Cd zRP%okt1f{=?L`_=PDdIhe^rK|MmPVTO8Q%r+JvMUMCs-y^|+#{F=3Tz2jdn3s09FY z^9#7*DfFr@C_$CFAL6|V zAlr~l7p>vxh;+9Os%b}|Qo8ghVx?Q9Vt(t0axZ~FK7?Fuyzu0Ri$H7^gWIk z3sxLfeLu4hSLIxy4Ka1ewCbyo%GFu*tq91{Eb|!v)h|`*b-*q-vaBTr0IQ1y9bIO{V=Q$Tz@(H! zRqCvxV8H|IFo4iyP7&ls24E6ZsluZ%I|Hl06|h?aFp0vtL=n1~CvqRllA)o)Wj~T+A+zcwgz4sglWQXAxNKOZzJ!|I1ZA(H z77IFLQA9=%i<{u5!3rJBypE;qQ61QwM1e)|bcH>OrVSoyHnkg%YZu|C@KT=x43QoM zgeSt)X{5`+SsfHi?Y_oTmp=*9oxoHVFHos_0J9gEE&-M+;TA`@sVS=u9aM80mt!vv zAP*t?X}J1Gsuf9pKvF3b&>XmiB54%sH^I-P8RY(jkn$i3uu%=ENu)fC`WkSPqUsM| z3Ej+vA!bWhGkamSj+qivRi~mpx|!)v2?^^GY27`43lO@Q?IAD;Yq0hlVhO6M=KxJN zr;J&afa$PGH68=q12sw&ej!|Au0u_bY|z2-PEV<4(ZI&|?218zE8fS)rFf|F58+t} z#x_RN6}KW>aW@{S{EK+DGdY&7c$~@K<>TM*$oveCV~*3S-I@N1ia#KZzf?PvE7|xZ zkn;pdYLFID#&l4n{;*o9e*lO*1Ct+IV@VD~g3?Ww9Iq#^##AOGdmd%)DrA+Svc|G9 z0bPB90i8Yx^fY7%Xq5&XK|H~t<&!{nA&YZyV?~)tJ%|XU`Z&LRtQHj=R;kaR{0IOGpzCYlntf@|*DyPn;P=pY6Rbkr&AyP) zkPFVq28E*APSzAPA0K9AX4-7@F0#-D)qFyE#T>-3>xyps0#dmmZ9Z|jKz->H19f^B z>Jg+0)EU#Inx6zvCr_&8wIJ)1FoNGBm0jL^>U5P_fh87Mz6DLbl+B)e24o57d=2^~#7SS{+)1F1B1;7La46IG-{^)H!F-$x*OXHYI;blK z6tOi;R?9b_wN3GAm5QFLF>M5v9dOOXITq@m$VhQkYMYC*Qu{%a6>gSI;^w{N=Cqlr zsvaUpH)s0muqmywFK5GLl+HQRiC9Jch)n*u5lpUkAR{jliM<#8OvEh}<0v9wm^S77 zV=J<%zK#c7OZ_o~DyuCH!pbG^8w9FHB3;{o%>r~uHmo8<&cCWlkx18?$I0C)`$jgb zioc4mIn(+)G7o-gMpIL;J%JK*En}SPtuhz=ro&}L63oN8wJeiMJv^6MFF{hTipvo; zHP@rW!E0WET>d3kpPXFUs_Gb&rfWMt)Nlz4L2c&~SO{u6KTD8FB|#>Y1ht(n1XXAms59e@zb10mp=(9;Ju#t z|6*7C2;qvC@hCqLT<7hWIaPBi)*@VfI3CX;q3wm@>iZ!PZA{#TM+}jcqbjPOfPWF< z_$yxt-qa&LXLfnTnFv>xxH!0CfOizOFfb1(+Zpf?xQKyu2wa6g`B#BuGvL}ToL)VO z#BU>B&1(=pWPmpTUSi;O1YTp{VFdn&K=}ET!g`>YPGc{*7t%EtsnPs^wgM6aU&g{67sq%rs~s&AeJjn=zaBOL<5%ZPMQ z4yg{x7+;hd0W~o$9ug3ok;C_Ml+j97IP>62Js^OoZfFNBq z3F&J@dgN@C>gv;TbPeR=IJhQlmC1CfgEB`i%+Ap-qX3aMHB3SpL$5S7&QPgyw`fW~ z1cY}IX(mgl3CbLu$#SA8ljXz#lokAkPr~mJe=YEz-LLWg1h{_>*Pta|%vBv+nqg{| z6VIUlkv2?L(d|Im5HDA$U#*8~23wju?OM|uu9e?M{>i|mqbhaUR@eYQwFO{wE&F7p z@jHOM2Vgp?Ql}pcOCDgK1PI;2jDX=tL$6yTiVF%D&vY&R{R^nWj>le;4wrGutVP=o zYqCMDamx^|Iu8%Jwu?iGN5WFH?PB3Bi|U}7c0a;&Z3`?ZQYuPXM{s(A8IrEO(W)wg zPuITHUr4gJg`mS_M@q6R&LYPnlYcS|EJ8-ray;l39Hv)JvhbF$9JcCYRdo(P=vp>Y zFs!nVWW!o@Z_aAUmd)gwnzkPhbZs99)2<_>ERGD~Dy8a2mQFqc~X6?E6B=<_-A=2rX*!qv0Tvp+zf;zc~l zFTrCovfC~xt!_rnbp%<3z|91?3lEs2ufcobJ^E~G&cezHi|q7@@cb!Kmm@N#z9dtH z_=3~)Im(=d@{0M0SF{i`b2^?w$byzra~ft*l> z0$EQma1R3CW8irNUO-^x`|#LLqA$at^zV>*C9^+-z(*Ls@t@j{fT8@2)3t7$(_|=@ z_RNOq2RJoniAhyezeMlQEh*wgl2yhtQ5`OGBuL(>su;p_OO9aNfJslv%CEuW733^Q7FXPiuqyu)pRA~~ta>TH9zeX}F+8f*Aodgkyu9 zlhi-hy{HJMFmSfIE=K=cxQMzga$SU>i?T7I;@^*pm3k45@bps{rW#)7gEDBT8{q&E zq5lau4Z#qH`*`?gk@`b8!qb1zgz3L*!t_~^FhM;QSRR8TCG^|i#$*0sIfgYHA?P14 zVfr4rVLbE;SdhlBm=S#Ni{Uf`Lo2eepnh7+zTpJ@Zn*In&&EW*3yv7+Ukaxo7`itb z3ostQbjWED@DcjIgwya0#l0XFz`qYEx55!W{X5|_JVVcCW6J#TO2lP`;vlVdHujm| zSSS596Atnp!g&5R9P@*;$L8WJ4latc2HbfG()n8DVmQGCf0+pf`P&iyN4SaQN})?n zfSZ_3{r5GviRqsQjsHG@&M(y9L z5WiHX#pvH-!a;spE8g&eBh%>*nK1o(;l_)=(MUPpK+xZ9!t^IYf36)3g9|hJ`6<%& zErB|L8(-JDr7&0E#-~16tJJ^2g>i0Krqq|=!f6*yk@njov5kF{hNFLm2?xB`gZRrP zjefz=<8gAoxeSgS*c=iRZY3|ABApw?r@@8k;_mPlCZyelN%Na<;eL(07xloQY>fU) z6Aow{JP$KDTp0IMX+vFjrvZ*Mw}og9r}Ls$fHz2w1D@$q<+&<}k1^dcvB+PsihbQs z4RCBN{U4ZcK*E)KN7Ju*6s7aF(M^;|Hj z->t`1mNGAa*Nt|KY>`Xk=dKIj`g=Bx9)q_oN9DFG-Z&rJfVb%v<5kP9;S1~fdq+q6 zdsYr?=M}HOBR?e2+AJ5o$55BzIX45SlsB5+MWrL7c-K{NW33JZ_72o-8m!~%r>lCp@M8Xm zyyLh2LV!S9vstK>>k)7ioRb#}&RrLf!$r%v>&|T?znRMucFAjMlxy4Pt}`@RAUEg} z0l-`SgNo;ML4!LD3N9<(MQfIiZN#Sp_>~96+u!mX0J)6Mia|Qf?{n8lduV5qbv$GZ z-Y%B6hvf$L*uY5F#-2L!y#sjz!n6}@c@QiP2&EWo?HZCJ-~f%(&-(%VQUSjE(9qZ} zw*yH;yW&*}1b~N^$pSnZ#|FA}^?cJZNX7fby{k_-tEXFDKMhhxd$;zSInX<*I?%=- z5%0v}6Ac@?x_jg$l5^LwalCyYm2y?c>QU<>p)sQM}X_ z@M1k1b-GA4YR5g3(n6z4y$<(VxI!qB61WuHG`R1;1%Gc>K7b=07v=bd!Q-Lw z`3O(MAHe)`2yQFFd^d?@!|Aj-AAoxZ?%Qxbg!?I6@Hg#n92CLLhg%32{JqrzD;Wym zI5--BG{$a$yA|$paL*rsB{^L1_bd#!AHva)s~{Zm?g-_t?!d(WxVzv!0~h=q<71Zs z?l!nj!v%leSdJ}YxY}c|YYP|r9f$D0!TlQUH*kN3b5`JG4!Cc?Jq7nPT>DC#Rl{|_ zefrp-H2QstvR?*#@OL+0KYkocOt`~V1*x#yPsHR1_i4D#!3BRSPr^hFcL&@*!Uca% zW0&CtxYjd42VC&?cbLEKfcq0%RW z4!;loTo{2jz%_M3-r<(Q9Syg;3r0TNm2lU>-3|9yxG%sx1h;2B`U&nAaKYcf>YMvl zs&Dl>z`OLkfI3_WdI#{cL+};g%fa{)hNFS|PWkm*h+ltcxj1lmaC6{-ehB0J^ClRF zn{lfVZWCPa_j`n+y=W6$H(c=d2Euk9?$^V0!Ucc7M)*JB-m?Y!nQ+11&k=qT?xcQv zc>yl?`w7Cog&#_Yv9g<8-N>zy96%yd%OHI zVRPO9_i?yu*I=;%_w{p78sjDg7yQv+-3iD1&%yw;_(X4rzQ%D2_1S1)5QeB?a8~lURblwUj}Bz|ASg zbuYO4W?&%;H)kfc*#O5q6uwgO^;wup;7;>1sL8& zeIAZiQ15Gm?7^j*Kp)z08en*Hum_IU1-}c&8-W|(c=w{e}?0gxj!9& zFx=c_&|9dR3w_=_Ylq{7vwcURZ{WCa=N&OF(77nDf#V{4DO|AV4i?(HB=wmN=yEvD zJG_gy131nDyzD`}&x;o|7#qBaKz+~4 z1FxQizBGEC$LrMVJQAh8<@p}RHIL*tj(K#(am&*#j#C~`aa{5siQ|xGKU+|ShdYnK z@$}{vIG!0SN1fa^4v!1-Hb**1N+_T*(vE~$|T&E~mao_UkCDxf0Af_4nxT{k~ zPhXli0$+hC9)K|8>nTprQHewXvR$lJr<$TLOv({(kQtp&z^-JGyp)w-aZpew2oY{a z`TSzUSUw&q=9+pEmbE&CzDfgin~M%(y@|w8C|4wD2o$F*rU~j~3O}kLp^`eZr8GKF zZ-Qt7&9~&8748y&vfAKLr{rz3Ti${A0F5EP@ zxW2BTv95mc$Z&VCR8~`?*fiKPuzm4%EL(dA2Sye*)HO8KwM#i!2#&n#V!ea!x(FBf z*iaaK_m#2ayRHrktDfNju&jG%>|GZQ?{B>8!e)W^uFFl>b(x}ksNdfCVsQ#QSs{5R zf~7wYc@QiI7p!0xD7W_9G)Org>BeWf#`=4Pv7f^Drfz-;Z=`2P^Oo?Ees?FG%WZFnOb0+#6yZLYsr&aPOv0d=PD{TZlj=#}Qx zU>@eJ(ZP*OjY+WA1UK|__ipX#H!>Lq#EN@>NEN+n{uuDbe4%v8VgO?*1^^{^n4@{x%cY zJUB86W!xXsH#XXv4V%x%8A$Geg6IM?Dc5T%;^7@0$bl+xE91@|?bz{dv9rc*v0N2( z?%DaeJ3Z?B+P0Tlu4C7v+>#TRe)Y~#_pqq*Tf5F(5Pi`-4Bi^|ux0Lo*u`#nbQ3{7 zxUaGXeim3CqR%|2SZ+3pR3-wk;osU_bJN<0;tV<9XMb1kE zetFm3I&TeQKiRd$tpwmQWREfP8P?wM+BA?l{(XDpAjZ}s38aF@cJY}tMs~5TX=X}I1 zaV`b-8l69Y#U;)M?2EzNHEw1Z!Tz}Oc(?i-x9Sr_^T}P0yH(B)1~Tif!m=n{-nQ3SZYp}WTecD3^_x@bJh5wE)cLYyH=*Od z9`)5~S9{WV zS5TG{_A+)JP&ogw(<7Z%XvzB>L>N8)LEG*C0dGL^fNvjuhb42id)g(4jG}X6v)!^Y z-5KX%NNh(J+fG8H_EkVb46d_9q<#VEo`J|RjH5BTIG}^8O`+psc5E5wfaq#EUIrbg z>qgL#ir%dGQB&%?q)E6LB+NeBJzbMf9DUxko5{x)f^4bt-%)3obF-{fB?tZ}{!VlcuVL#?Rf!JRjgMYr2`yN)y0 zo@=4ue^cjHICEk*yJ<*l#TvIhY9Ea?2oTNCC_WDq;N&-L>B{>+C&us{;W5mGc8QyC z?y{a?SAHK|Ipo|8;W`I$8{E4HvmBR-8gz@ z)Qw{#tZ{w$gacz5XsXGfg3niWjJs)s^Dj7Wu2p+&dzr-!MC6ZxXSMPi#l6KQj z^I*I}6qKS>4*DEZ#SY>J8IO~wyWJzB&YsB4m@GCz{L;Wv=T2Ya&i4rP6Lgi3zQjTS zb`aEN3r6W>JE39(%L9^sjLwJVuifa@oP%bbeX-pcFoWAS(mlVjvfc9`Ei=ConL$MQ z=QZYo#(leV|6DqufBvZZ=XHn#pst}HrJypjAi1TKo@LGl@w1oC?*UQ@9T$O0EPaOJ zbQ#16jrkKY690_8UE?N@J?dP%>zQ1)af3;^?KVeu+mCnHJJ@Ttp`VrW;~g=~5{OW? zV~a_|b3342Axf{ZKpDoO$SJhy^*dxjxedSIQ}9DbORUZpoEh%)$vz$Y-C^F<{a-%b7se0XTI~m4q6@{>Whwj1bX~& z5QP!+&!`@){yeJ2ApAb6M(nN}A!W{^%Fb9&$`4Sorb7S&$tric>oCCs7L(FN80ORQ zYtr*Q=dJhKM}fs80K?3w(*$59js1gr_ z!~Wl`oqK#$SDom0&SoD%fIxUdD1=9V@HmhMG_)z@QJ$rQk`w}cq#-#6atTRDPJr?m zk||ZI*V?Azb7nN{c-85(!FM|qt4OU%r`4)ssm|1~RlN1qS}odJM?ZS+_xD?S?X%B0 zY3oTZe~`V`UhB7h>$iUE_gcTT&c*=DBzIK)1w~>CGHCHWubi2wgcoLGP+7K=D56gG zeR*&W<9NaFXtS|2xT`Jcj;MGVK6Z$CjT zN8L~IalFd68uvd8D?VWA|H!ZZKmGd8YW)ZKI9ckChpD%@&zL5kF-?BpH~FmJ z^L(6=YVx#c@+H&cDZj}>ev>D)$-nT?V)cZne}Cv<@n=>qv?c!5a7RcZDu2iZR^ ze&i%Z^aBM?Sy5k2M8V|I1;u=v+wr>_46m;S;XZh#72JZWCIT|{^r;4kbluwMIzxP#;kB2b1r$2 zCnByTKy8Wt;c=g>9yM(BxUv;5LV(9pZ1t61BSC&8+B8gn4;r@mwwb^$%LKw@=luzM zL?`fHWwv~_de}_hcTD{+`t`r-*Z+dn|6Zv6=S=;7GxbmV^?&HsAJqC6LiImw>i^i( z|7XAczx(w+rS+c+)&GR4|5H={pZxmI`}ObF`acWRA29WQkym2aZ-TPlKZMz@#j;=V zr6)vF8e>zYLqhu)sRi!ROHsG}ys`e|gT(raJnq?jO++|$=HF}+i~4m}ZRGbLj%M(Z z^vV#+HK@{k%+3j(E4|1Kwm#O-pIn63JO8G}wDoO|dBB%Fgd(q`z%6F_mZLpO`n{3S zgI>u}Z{$7?`ChWbi{8jdVAhA!m%RqXXEA2)bzV_^Ibs;LmA-Gni%8P9J8Byy?rq3e zw@@YQ7KA|5T@6QWz9@{n%tv580A?&z8kF2>~PJa~QPXT3%5_pXj&HJ8ZOsQaDXem+lAN2wHJDuP`w)jgK< zM!C}yQpG*fJ2+w%Ch53AI-{RN(#(WQH?nDh3+q0YHvm17=!vyJ=#O4|tv6=7Se+jQ z`~rZ?jFjfl&uA9IHVUS@kM<_~_ZaWRyo-_$vC)Dz5OpuZ7emL*81&|f%hp`tEr`0a zWhkTFb9vHcjQcg(Ea>sZL`%e!y)}X4cW0gw99v{iD6QwIxe!8sg_;z{rIl;1(qA$Gk>Ry%6b_cK4k;57DrUBUj{kRhSw=rTI||v_UNB zes7t8ETJdr-jCe^9(d=ou#Mo6Ss;n+hG{^f%MO4+1Q$x-{u^kaJ${pi(zv(xqQO{2 z;QjcbV=&-AXtdiFgZz`QDHOH4SUNQNldP>5qu4a(MK+#_l-%P@dY54ECu~4C=uTXn zsi&jvA9$UD+>EGgdg)}sd>rs*?ea#r#~JY|Tv8eIs|*_H*l&Eb-{O{F6a3m4#CYxZ zCaM)6dTa#5e(5CMmC%P7ixXDX2`4CO!!k^OQrQU5R9+V9_ZSp?9$t3CJ5>4)= z$(#o7YUay#RTt5PY~&SrSGvX6F0jOTx3~o3+9{aIQ^%v86*0ZjOdIR(IYydU&@G{H*6=$u9($B ze1vw-I;YHp%P?ifRmJ~5h*mF+ESU&tlm0ZpzmNBxLMjtiA$AdU8wd&MjBKg#5JWFH z=e=s+dKcXL`Wg^g?k_PUW>9^317Wqj-max@I>FIjBHJSF30+Jd?n6QmsdFyMXzu~u z7O_%d-dcJ=SgQL3se>!}}gWBR-cH5GN26SQ0A zxqCIxxU)v&=u$PMsmc^ppfh)903qfpEP*P!;R^M`V)3kDt{^xPi$Kmt!SIH9Zw-{$ zN`MOCSlo(4vsf2LS9|$4d25$=`8Rr1eNZ;$RY^qiDvtnBDQ_6e;BYj-bc~I8S1$ma{C3yZY3T{ywlLiW}#+pM}$b@(j?& zxTkw1%##m5_b-U>CGIJfR17~|Um@@vdFcE<_a+7WJB3^Vzs?(5;luwEtyCa`yZfs= z*2)7!ika*0TJa_lRPqdpycq@VxrpL^7QY`!{a7S+pEtKfS0x%sOSY+nOB=~a&{yDB3!`h31?8(*~2V@QSQGwk$FV3 z-G}>Ez&jg zj=qaByMK0=vjX*!@1S!^?#Rn0Q2uI^2~wZ^PNTK|3r)><-z$M<{1C$8jOTrMv1jD< z_Xsrb{vdOkpRY^hC8muEAE5#rXQzk zg2)T^9#BG7iJt_FFF*tc?t6du5})Gt!QFpnQ6Z&DO6cvBdn+*|WS>}Xr`+qc^^b^+ zkHlhB&U}DH50XFjk^GcF@;UKTKhZZJI)4(g5KXvkry!lXM4%>JRv2jf3_$q=^FP+h zTEG<&gJ3{N_7pQW1yNr^%My2h^+oMpQYf`QY{u}C)c+7WDX`+h%={F05YY~dF58UC6g{ogSpI;H+Ovt?e2cY#8pY;wQ?!WXVjLMd;lC;EE_k)o$_ljHa z5=wrG`w?SZ{}Oowwtp|dQbaBSnFTaJu#~r-@r~vCcNnkkvnhCz{G@_>thVV^wTb&w z0F%v#@|yxtx4YlC>C(OANGX3*a#Q(^sJm4{*q5_>-K`DSWA4|PJ({d-5NUmmU(rj$U^!IbH?irVd_Hq#20jA9?eL_k&|>Tbs-m_5TXxyk>y@=nOC6Z;~w_r z#>fOLp`zq_=@{qa4-gR^?|vq7al{fq=kq5c)kLZ(dOC7Rill_N9gH@Il`$GylUlc2 zVDoD(>%zSS=P2qfOri@fc!d%*+^c@UGMFq17LHq|5t!wXRe3mR@W%yjqU=hrK(u1H z7*tw3!E9F4s$#5^Xk@B(gNq#my;qjterWL|shvN;y;kkR%f$~QPDF_}7hQD0n}QM; zbhm13cXbJ~kU!|IZtzNy@(5$^wao|1mzptuk_{D7?2M| zgub+U^5iL59}g2CAD7SaK_pVbsyG{oYzB#QtdRxm`HArQHUX}MY$?g}H`$d0wXd?u z2;8~fI5}X@xk^2f4Gn_KnlxP4lzAqF3lv#@N!H?G%%0sQDm!22&>;9=bFe0F1>AAg zRUI3(vPcB}@yRRqcg_wH7S_KSNM=B8HoBKs43yhn+spxt41W4BApGsjPNz{r> z5sZCVWVOYnL-n~^WEs0ACX1Lr0%Kw`K;{<6MJ3++<6cy4ln%rsB{4kRMjmccUX((x znW@;c^vmYmw2RPd1aqAMP$kB9oQr-j=KdFYFVPL^Vp54gxDxV7wzncYEqx^(G~}CR z5neguN~{!YiX&U04WV0KEcwDmpi2(<@Yi|eU$f4u=tff1wVQJy>u08z;A~%HzD)5s zM>f?@=!|)n(=F&kW*>e)>VrpteRLLN*CuH~PQJiBY z>Kt-^zDvj~>Lzt!fFsi-rYUnWrh(~nJ8cg-XBQluv`+(IeAN8`6C<6KWOqh;nKnTx zCUv52sgl;U82Pg&1DBk99r(QT*}K`y-aI>di-(-Os;FCr9NlB&=mH(!zRYQqH6|(l z+RdDFu5L73J;!#lG?NLHs}YC+S2rq|=A?7A6hh*qN}zh>>P3dDOEUou$<>i*qV$E| z*@N{Dgk^gd$fJ~3)r;Z1_RP4a+)zxB_njfUBK64ZbHEkTG36)r zdu8|YK*(LUFz9t6vBCy}7VuW#78S^l=eS23c$@5wRj1(~UdNKCJ41pN65LC$LG8{U zH3|2PvY7nu5>K5VAyKb*uQy@0SG*4?K>nTELSqDBv4+4zc1fIhOux63v`sZqld6|y zsJWYnK}g(3*&<`-ikTN`Gm!_FNLCtjpw1h=+?y%dT%;b{Qzb^{=mdO{FD3~KmY|ZPDW2);*Yrf;Tsi!s3uJow0y$t7 zh|i-@m~<#h7J)Pyx;B{wGE)}_JB8_bMY@r*McU1>^ls`*H_PlgEP11DD(U7r)6EL) zX6I1d$k8S3=JNDzwwi7(x7|#6qi(LEn+>L$E3}(Uncaxgl9N%|&C>L4>P_&C)a@E1t4+UM$TPgIp>CkU6(C1p{ONNF{78!$RFoP)7LEM^T0Kz`Z3;bojE!HU&_ZMANf;392MnJ1$U*%fuwj=^h(`#EkSH41Rtnj zMcoDt4DXyX7>!&zaoO^#mah1;H&^!y5DpRsb-zuFE{fhLY;eEahupl1mO#3TlM|H+Ol09iZ}vV~6}h`afKPCjlff1j zFp^evilW&_a3z^!R!xwEgbHz?sw7Bu^+nknn{r789d-Yhm!P5RzFT%1wzE%0h_Sjv z3G(|qLy)_Blg6%*X^}IKMPd$o(}BTOL}F;pGks8NweULosNisBC8lgeN_rl_uXcP{12w3tRUdL zOvC9cCt`8{WNJpix|IKl-WbJ)sWlZF0zm8))ksM5JPS=?!(#?r^1v=KgtbCliJcO? zb(p9`q=Z%I{PY@oaUTbH>Ny{{nIn4k;+o+84>>1On@DuWlXA$08%^xRAl+^8c<1$U zsz&c5sSZBqWkK1s);D#>>j4(rxMQmXSFqTE6Y;K&y4Dl%mUVI@CxF||u_jYu??AB) z?A0swJ>K48?qab8om?iw9VT7L02ntHb#gsX@XlR^!Lxizuie>`Y(Ci3#g#aYUU(D0 zHRa}7nf-jtxa)?Z?eTV{PXIl24~>O#u&KR;%aV@9xn;&b4df)+g9cR7!%LgGI;db9 z+0ykKnKGC2bjS2)rrs1|FLluu4!CXX>Z&`)xvD)~t=vB(=egtxBu7tk1t3G$-k95d zLJiGrKyp@YW9=sW)75nYGXkJwyd_n(qhn`R$APYRcehjm%$|dsQjGgAmXQ>p4Q(CW z@s^z&x^se)p0T!gdo`!OoW{m=yLPSH+gP`C-^RxJy*oEHHil}o#MgKAwEnmD$_lBQ zYHiC`Ri&4=Cr>EURL#zg&WsX{ZU-f?MvnFERKWUpz5ghu{nmw^>qE~sgr0YYp6f!- zyF$-<%(I>u?Bsk{(|#`G5d>peWCvj0+T#a86*&Lc?L*?2q5lMGepj6!2 z79RC1R^=8RWfs433-3q(???cTGK*CJk1~r@0FN?@UjUDTpY3+?dGse=j%xa)^5~Zy z-q~8E>l?|ahYO>DQknTD!WF=|!O%(Yl?s4(DL&8-5S2lj`V1 zatd(0D$QOp1@j2&$Q4oG-P~%}&Ot@K^_@_`&#CF4u)M_jGlkj?jXri}v`jT^$|C4X7W8E3b9Qu6Wbo zP{9_ixwEfbsk+@%rp5lA=0kBbBcyYL@fg{#UN^lM}YJJplRZkGjW@yNocCWZT2n7iNA;yW7wz+NQSF1MLp1Eryc5 z92RwMhr`st?;DTwG_^U$o!f#-*A8>B;=1;hx`VBWBuA)O%(g|-e$;jF*2)!i*gk3R z^U8A>Xk9$HBYrGAPl=SZ7n1|p0r103U57TCGulDf<_*E4e19g@95mZeS<-9TSv#C?(MCI;`W|G3qmiz!}dD74wN0idx+sATH9OXn#VWzv_n>b z1*qrNRc5D^FzRX%+0{;JCbTML2oLjrW{Z$Lu60FZq%85Ei1ukMtxP|fUYxqNF!VHJ z6}^TrbtB^AC4yzK9X*FPwZ_|8u=V9WLHku#{HC-bZ2;Bci8d_BnBQKE=0%Hh zUB+cG7T>xIp&(L6NH9GqY0LOhP(?-y^P^?UVzuqk^{zNBOLx*QbuzAF&7tp%mP2;x zG$)VqtF$>lJrGZFr)DlK>=m5cPpUpuPBW7}h_V}qP|CYEkToc4~MKIYCn`UKZ<$A874HcWhuVAg2Zae_4*X@rLj0=FrHrP|m>T z*T3L|0zcezTuq#uhLcGgpI>BHyW-uQa{0}AnT@vv6i7XX;~_pwUBir_AlEQ2S}Ynh zbTM;T%)}2eik+4wEPE?l(Lm_-huVmND4ch?>zi@+5>RII( z2>Z1+$>rHub+@*+#Iw8G3XwB=OCPZh)EZ!!l~K3iGiDa+V#_SlDa|Zw?FO^fE)-c{ zk!Y8-g#LW{gYmRzSx|yJY%x98*&B}1zU|gKlmhN=)N79%xymSHzGu9Ocxq-KcteQM zSYR)UwY;e-4!380!m_DTS7nG#S{}5BCpU3p(oXUJQ{m0jmDskPZ!E9Zd!BsbddP1> znA4`w5Jq*HMeX;nRj%qvGW#8fmG$Zg2GkOxyQgz!6PLpWWkLk8fwBrx&f($s;pR@9 zD4%}3Vs7ABg$g8w9K5%;wx#!>hOrvKnFchX0H@mgZ^3Ep_7r%1mjFvz1zBpaXIhz< zl_eKSEsDjAt)T<#v`uMurTASk;MT#EQUo$I~sL%m!$g_Ca z8{+M|8H)Hk>$$EzMR!wP-(gA@y_sWN7TejQf|cRFMMYVw)XG6oZ0|U*fk1XE4u6i# zG-#tg8PM3#Zteu*&b20VX%5{J;XZy_ZM*J$?9#>oL~uGZ3{dsbOrl$eg&Yv^TbSPE zk~9Cl#>N$m<&7(HfutbTt>3yE+m1`lR+O)Bf-zy->GfyvoB`Ih!*71uFgOV#H5zYc zcrXRP2Ih@`KmeEcq67$XAfGm^ZTE#=3Q$M;u)s(&n5w1YSUU>^Gg_`GY!|nQ(q`H0 z7!Gm)G)UlZ-F*i zcVl?KEnw?x2IzAM;4mnTa7m$v!yKB$VL(IYr6w)~x6Am)jp|h8K5XB;Rwp1Bu7x># zYG!!tS&#$oZ`c^uTmLZx+i=$KNfC00vZ1~$lnvx;oUNZ6VvS)h@Ed%eJH;g#%RA_7 zn2XzXkiN8!9`h*-i&f;(PK_30aEL{lLsPR8kMUZkFvMgL2yYR$ z3cJ{ER#$|CBt(d#!**L6foZn9oA^B=B!)56tudwXV^ee#d!?Iw0=(KTEVwwouY(O0 zGO&{V#yk;=WJjkM(2j%^*`H`}xU<=5>N>E((PRK>bhhZ1x|~#9Kog+KfmFe7 z!w82d2>Po{Ksbp7wf7vhl9k6`F^J^Sx<_RnC1L@Dh+C(!Su1exYsZFWE)+q!G&=Q5Qmx&g9pJB~hFMqPyg&3-=`_AA zhB6YsuD#X}&enyhRy#M%42?(~+t3cti&-)t<#$e>k(!8r2ieP7IXkCm z*qP<8%^H=WrOz!U+2QuIwO~_%9^^Ja%MgL{zxQp4BGty1xb5Uk6p|8bRkAYtj_p-L;A55W5=`1*5izWepV+~(AGedh&uh0@zjW(ow|Y~9G(eOodrYm4F` zWH)N7S$;M#NXA()CMVuZOSDL4^1HtcE4!^<46$sGc=NwQ!aTJt|9WnuR4JA2`xhcB z?KBz1Y=b_xv+T2lSFrv4Wa*o7bZEE1+7$8|=c0Rcn*nc0HXe3bp3&^Ff{~W7BtvUK z=v$@!ForUn=A%7qziAHH^P#s&=Lc3KQM1~)JM^vEsS1(NW?IyTrQ!$U`ync&M`WWpg3FmZ@0? zU1N{@Af#+@oz@e^J>*1&^dS6{sGkISE0hKO<${zx2`4Q+1 zbk#d>AaanFI8^=~eF3z{+=ocZ-n-fMrNrCiY)yNwb6!g$ZoM-(?fVV-yQXHT3-Nb5 zN7BCUaZb+933J~i5Yz6_VXca5B+NVoi#ko?h$doFsXHw8jPD@o+wK5Amc3TCNQ_~I zuK7RpHj&w&>_Tv72c!M!9`_H~Di5zh5_d@m2YOVhW ziM3E-_JNQP^e5VE9nQg+%VAOateqb5emcadzUB&TZEgq&^;Ej_t#gOd?=`_D28tss z%u|)&s@fgrPsdX7Hk9Gt=~^zr{q8imUpm0`A#b^RM-V4J*q-R0ug)vz|sF= z0o%o93~#ds{EtKMX|?m^(7=Li^X&`%|FBO+)Zzp(A_od&uHq&l?8zMmN)Tvexm zTj$k~{4q(}G{{i+Zb*5Gh3BW2Y{`a)0(2gFn=3`55TD3igowZ$*{Vdty@x_Z zO4fl4`T3WCd`ADs#Jmt1sd120Tm5HfP%wSyklV;Hsg;>J*l-ZvA(a4XQq~crY0gX9 zL7GcLbfD+uW&%IcY6y-=bYW6hBip3)9~zb*^cRqd-UA^~6G}Rp?i(K_^lDG9nNw|L z*|ZEYzrLETfKB$xSa{dsop!F^BMWns2)-+snNFF^whWCj75i{)$gvY2n$rm%3`{FM zP4`gv^?K*MfeD;`j&Q8?^5hI&os$f~^|!3P7b+65XU{5J{|4a`45J^1xYpQ8Dvh15 z54GMksqMufzL>Ru3`qt)%rmnX`7(Je)5t&Pk>C_J!SkT%7F%ne@w#y3erb@S2?7-7GF^VwsGq=d$G*bLsq-HQXBIknOKS z62xB*8h^NY=-nL6$($Rq4J6akC*2nVTKb2h|2V`9OIDmynBxqGj|BYp+@ioc%_fOv zqSY}CmPG2PB$}Gz#t=P{;|!-CQ|M1KHS8W15fuIR;KUKKNu2jTCdQroL`&l_Ijo*H zO4og3TgQP&v3bOBYmD0iDUyRBTf^=Q^AS$=^NAWctAWGHVcQYo%(sI!pUIn&s!YB< z`|yo&uD?6#mkZ3+_MSL-PkN4J4k$Zh7HYJ6Foi;|lGo@z%%B$ml}kfFBVknqUov zl&v`-vkx)*CKiV)8p}M$hn_Uv_Gr!6$rCdA#0s2}8j&x=WTR?oR;iF>S_)^sZYtP3 zJw-DAn;+PnF*)ee|DZH0&gwxXWoD5bP#|b8%Wf~0z^trdH3Md+$mI8iCM?Oq%{L6@ zOv%K}&~R=Ra08v4MNwI?c~uUUK_~>XWnB*KhBnE!R^$MJuEoCHHpwWB^hEP(#|EX6EWSNz zcCxRVYKpV6xOYql>Z6s+=3uQ~S@MdF_Vcr;clwG>(vUT@dVQ+576Qk+X1~eSjzpI0 zW=Yc^l9rX=SU)YmCR9uE#%}PHGwlO48>9{IUh*dWs>O`zvd+mKU)cf)7S+>kHbb~! zOwc{{z}{JJ0+mVFmm(7>WTCO#I5`00D|pR5y(u*~Ta1Gs2O)31JcsEICp+E}9*de1 zjY&TRw$ZmW!o!rLx?6oiCR}dYG|deV57I*6fV3p@{VBLX9hso!qM)r!{%pA-mtko* gF6BPV5W`G!x1O_Pw^ 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 diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..f2c1554c --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module github.com/mathetake/proxy-wasm-go + +go 1.14 diff --git a/runtime/abi.go b/runtime/abi.go index 75306618..2b699b46 100644 --- a/runtime/abi.go +++ b/runtime/abi.go @@ -14,5 +14,5 @@ package runtime -//go:export proxy_abi_version_0_1_0 +//export proxy_abi_version_0_1_0 func proxyABIVersion010() {} diff --git a/runtime/abi_alloc.go b/runtime/abi_alloc.go index 1c4bcfff..5338bd98 100644 --- a/runtime/abi_alloc.go +++ b/runtime/abi_alloc.go @@ -14,7 +14,7 @@ package runtime -//go:export malloc +//export malloc func malloc(size uint) *byte { buf := make([]byte, size) return &buf[0] diff --git a/runtime/abi_configuration.go b/runtime/abi_configuration.go index 3db8f7d7..2fb0e534 100644 --- a/runtime/abi_configuration.go +++ b/runtime/abi_configuration.go @@ -14,7 +14,7 @@ package runtime -//go:export proxy_on_vm_start +//export proxy_on_vm_start func proxyOnVMStart(rootContextID uint32, vmConfigurationSize int) bool { ctx, ok := currentState.rootContexts[rootContextID] if !ok { @@ -24,7 +24,7 @@ func proxyOnVMStart(rootContextID uint32, vmConfigurationSize int) bool { return ctx.OnVMStart(vmConfigurationSize) } -//go:export proxy_on_configure +//export proxy_on_configure func proxyOnConfigure(rootContextID uint32, pluginConfigurationSize int) bool { ctx, ok := currentState.rootContexts[rootContextID] if !ok { diff --git a/runtime/abi_hostcalls.go b/runtime/abi_hostcalls.go index ff0b8178..bd91a999 100644 --- a/runtime/abi_hostcalls.go +++ b/runtime/abi_hostcalls.go @@ -14,83 +14,83 @@ package runtime -//go:export proxy_log +//export proxy_log func proxyLog(logLevel LogLevel, messageData *byte, messageSize int) Status -//go:export proxy_get_configuration +//export proxy_get_configuration func proxyGetConfiguration(returnBufferData **byte, returnBufferSize *int) Status -//go:export proxy_set_property +//export proxy_set_property func proxySetProperty(pathData *byte, pathSize int, valueData *byte, valueSize int) -//go:export proxy_get_property +//export proxy_get_property func proxyGetProperty(pathData *byte, pathSize int, returnValueData **byte, returnValueSize *int) -//go:export proxy_continue_request +//export proxy_continue_request func proxyContinueRequest() Status -//go:export proxy_continue_response +//export proxy_continue_response func proxyContinueResponse() Status -//go:export proxy_send_local_response +//export proxy_send_local_response func proxySendLocalResponse(statusCode uint32, statusCodeDetailData *byte, statusCodeDetailsSize int, bodyData *byte, bodySize int, headersData *byte, headersSize int, grpcStatus int32) Status -//go:export proxy_clear_route_cache +//export proxy_clear_route_cache func proxyClearRouteCache() Status -//go:export proxy_get_shared_data +//export proxy_get_shared_data func proxyGetSharedData(keyData *byte, keySize int, returnValueData **byte, returnValueSize *byte, returnCas *uint32) Status -//go:export proxy_set_shared_data +//export proxy_set_shared_data func proxySetSharedData(keyData *byte, keySize int, valueData *byte, valueSize int, cas uint32) Status -//go:export proxy_register_shared_queue +//export proxy_register_shared_queue func proxyRegisterSharedQueue(nameData *byte, nameSize uint, returnID *uint32) Status -//go:export proxy_resolve_shared_queue +//export proxy_resolve_shared_queue func proxyResolveSharedQueue(vmIDData *byte, vmIDSize uint, nameData *byte, nameSize uint, returnID *uint32) Status -//go:export proxy_dequeue_shared_queue +//export proxy_dequeue_shared_queue func proxyDequeueSharedQueue(queueID uint32, returnValueData **byte, returnValueSize *byte) Status -//go:export proxy_enqueue_shared_queue +//export proxy_enqueue_shared_queue func proxyEnqueueSharedQueue(queueID uint32, valueData *byte, valueSize uint) Status -//go:export proxy_get_header_map_value +//export proxy_get_header_map_value func proxyGetHeaderMapValue(mapType MapType, keyData *byte, keySize int, returnValueData **byte, returnValueSize *int) Status -//go:export proxy_add_header_map_value +//export proxy_add_header_map_value func proxyAddHeaderMapValue(mapType MapType, keyData *byte, keySize int, valueData *byte, valueSize int) Status -//go:export proxy_replace_header_map_value +//export proxy_replace_header_map_value func proxyReplaceHeaderMapValue(mapType MapType, keyData *byte, keySize int, valueData *byte, valueSize int) Status -//go:export proxy_remove_header_map_value +//export proxy_remove_header_map_value func proxyRemoveHeaderMapValue(mapType MapType, keyData *byte, keySize int) Status -//go:export proxy_get_header_map_pairs +//export proxy_get_header_map_pairs func proxyGetHeaderMapPairs(mapType MapType, returnValueData **byte, returnValueSize *int) Status -//go:export proxy_set_header_map_pairs +//export proxy_set_header_map_pairs func proxySetHeaderMapPairs(mapType MapType, mapData *byte, mapSize int) Status -//go:export proxy_get_buffer_bytes +//export proxy_get_buffer_bytes func proxyGetBufferBytes(bt BufferType, start int, maxSize int, returnBufferData **byte, returnBufferSize *int) Status -//go:export proxy_http_call +//export proxy_http_call func proxyHttpCall(upstreamData *byte, upstreamSize int, headerData *byte, headerSize int, bodyData *byte, bodySize int, trailersData *byte, trailersSize int, timeout uint32, calloutIDPtr *uint32, ) Status -//go:export proxy_set_tick_period_milliseconds +//export proxy_set_tick_period_milliseconds func proxySetTickPeriodMilliseconds(period uint32) Status -//go:export proxy_get_current_time_nanoseconds +//export proxy_get_current_time_nanoseconds func proxyGetCurrentTimeNanoseconds(returnTime *int64) Status -//go:export proxy_set_effective_context +//export proxy_set_effective_context func proxySetEffectiveContext(contextID uint32) Status -//go:export proxy_done +//export proxy_done func proxyDone() Status diff --git a/runtime/abi_l4.go b/runtime/abi_l4.go index be73143b..299d2654 100644 --- a/runtime/abi_l4.go +++ b/runtime/abi_l4.go @@ -14,7 +14,7 @@ package runtime -//go:export proxy_on_new_connection +//export proxy_on_new_connection func proxyOnNewConnection(contextID uint32) Action { ctx, ok := currentState.streamContexts[contextID] if !ok { @@ -24,7 +24,7 @@ func proxyOnNewConnection(contextID uint32) Action { return ctx.OnNewConnection() } -//go:export proxy_on_downstream_data +//export proxy_on_downstream_data func proxyOnDownstreamData(contextID uint32, dataSize int, endOfStream bool) Action { ctx, ok := currentState.streamContexts[contextID] if !ok { @@ -34,7 +34,7 @@ func proxyOnDownstreamData(contextID uint32, dataSize int, endOfStream bool) Act return ctx.OnDownstreamData(dataSize, endOfStream) } -//go:export on_downstream_connection_close +//export on_downstream_connection_close func proxyOnDownstreamConnectionClose(contextID uint32, pType PeerType) { ctx, ok := currentState.streamContexts[contextID] if !ok { @@ -44,7 +44,7 @@ func proxyOnDownstreamConnectionClose(contextID uint32, pType PeerType) { ctx.OnDownStreamClose(pType) } -//go:export proxy_on_upstream_data +//export proxy_on_upstream_data func proxyOnUpstreamData(contextID uint32, dataSize int, endOfStream bool) Action { ctx, ok := currentState.streamContexts[contextID] if !ok { @@ -54,7 +54,7 @@ func proxyOnUpstreamData(contextID uint32, dataSize int, endOfStream bool) Actio return ctx.OnUpstreamData(dataSize, endOfStream) } -//go:export proxy_on_upstream_connection_close +//export proxy_on_upstream_connection_close func proxyOnUpstreamConnectionClose(contextID uint32, pType PeerType) { ctx, ok := currentState.streamContexts[contextID] if !ok { diff --git a/runtime/abi_l7.go b/runtime/abi_l7.go index c0261b9a..923e1486 100644 --- a/runtime/abi_l7.go +++ b/runtime/abi_l7.go @@ -14,18 +14,18 @@ package runtime -//go:export proxy_on_request_headers -func proxyOnRequestHeaders(contextID uint32, numHeaders int) Action { +//export proxy_on_request_headers +func proxyOnRequestHeaders(contextID uint32, numHeaders int, endOfStream bool) Action { ctx, ok := currentState.httpContexts[contextID] if !ok { panic("invalid context on proxy_on_request_headers") } currentState.setActiveContextID(contextID) - return ctx.OnHttpRequestHeaders(numHeaders) + return ctx.OnHttpRequestHeaders(numHeaders, endOfStream) } -//go:export proxy_on_request_body +//export proxy_on_request_body func proxyOnRequestBody(contextID uint32, bodySize int, endOfStream bool) Action { ctx, ok := currentState.httpContexts[contextID] if !ok { @@ -35,7 +35,7 @@ func proxyOnRequestBody(contextID uint32, bodySize int, endOfStream bool) Action return ctx.OnHttpRequestBody(bodySize, endOfStream) } -//go:export proxy_on_request_trailers +//export proxy_on_request_trailers func proxyOnRequestTrailers(contextID uint32, numTrailers int) Action { ctx, ok := currentState.httpContexts[contextID] if !ok { @@ -45,17 +45,17 @@ func proxyOnRequestTrailers(contextID uint32, numTrailers int) Action { return ctx.OnHttpRequestTrailers(numTrailers) } -//go:export proxy_on_response_headers -func proxyOnHttpResponseHeaders(contextID uint32, numHeaders int) Action { +//export proxy_on_response_headers +func proxyOnHttpResponseHeaders(contextID uint32, numHeaders int, endOfStream bool) Action { ctx, ok := currentState.httpContexts[contextID] if !ok { panic("invalid context id on proxy_on_response_headers") } currentState.setActiveContextID(contextID) - return ctx.OnHttpResponseHeaders(numHeaders) + return ctx.OnHttpResponseHeaders(numHeaders, endOfStream) } -//go:export proxy_on_response_body +//export proxy_on_response_body func proxyOnResponseBody(contextID uint32, bodySize int, endOfStream bool) Action { ctx, ok := currentState.httpContexts[contextID] if !ok { @@ -65,7 +65,7 @@ func proxyOnResponseBody(contextID uint32, bodySize int, endOfStream bool) Actio return ctx.OnHttpResponseBody(bodySize, endOfStream) } -//go:export proxy_on_response_trailers +//export proxy_on_response_trailers func proxyOnResponseTrailers(contextID uint32, numTrailers int) Action { ctx, ok := currentState.httpContexts[contextID] if !ok { @@ -75,7 +75,7 @@ func proxyOnResponseTrailers(contextID uint32, numTrailers int) Action { return ctx.OnHttpResponseTrailers(numTrailers) } -//go:export proxy_on_http_call_response +//export proxy_on_http_call_response func proxyOnHttpCallResponse(_, calloutID uint32, numHeaders, bodySize, numTrailers int) { ctxID, ok := currentState.callOuts[calloutID] if !ok { diff --git a/runtime/abi_lifecycle.go b/runtime/abi_lifecycle.go index e6973054..441dfb6e 100644 --- a/runtime/abi_lifecycle.go +++ b/runtime/abi_lifecycle.go @@ -14,7 +14,7 @@ package runtime -//go:export proxy_on_context_create +//export proxy_on_context_create func proxyOnContextCreate(contextID uint32, rootContextID uint32) { if rootContextID == 0 { currentState.createRootContext(contextID) @@ -27,7 +27,7 @@ func proxyOnContextCreate(contextID uint32, rootContextID uint32) { } } -//go:export proxy_on_done +//export proxy_on_done func proxyOnDone(contextID uint32) bool { if ctx, ok := currentState.streamContexts[contextID]; ok { currentState.setActiveContextID(contextID) @@ -43,7 +43,7 @@ func proxyOnDone(contextID uint32) bool { } } -//go:export proxy_on_log +//export proxy_on_log func proxyOnLog(contextID uint32) { if ctx, ok := currentState.streamContexts[contextID]; ok { currentState.setActiveContextID(contextID) @@ -59,7 +59,7 @@ func proxyOnLog(contextID uint32) { } } -//go:export proxy_on_delete +//export proxy_on_delete func proxyOnDelete(contextID uint32) { if _, ok := currentState.streamContexts[contextID]; ok { delete(currentState.streamContexts, contextID) diff --git a/runtime/abi_queue.go b/runtime/abi_queue.go index 5afea57a..2144183c 100644 --- a/runtime/abi_queue.go +++ b/runtime/abi_queue.go @@ -14,7 +14,7 @@ package runtime -//go:export proxy_on_queue_ready +//export proxy_on_queue_ready func ProxyOnQueueReady(contextID, queueID uint32) { ctx, ok := currentState.rootContexts[contextID] if !ok { diff --git a/runtime/abi_timers.go b/runtime/abi_timers.go index 59fc6296..922237db 100644 --- a/runtime/abi_timers.go +++ b/runtime/abi_timers.go @@ -14,7 +14,7 @@ package runtime -//go:export proxy_on_tick +//export proxy_on_tick func ProxyOnTick(rootContextID uint32) { ctx, ok := currentState.rootContexts[rootContextID] if !ok { diff --git a/runtime/context.go b/runtime/context.go index 78880a8d..7d907f6a 100644 --- a/runtime/context.go +++ b/runtime/context.go @@ -58,7 +58,7 @@ type HttpContext interface { Context // request - OnHttpRequestHeaders(numHeaders int) Action + OnHttpRequestHeaders(numHeaders int, endOfStream bool) Action GetHttpRequestHeaders() ([][2]string, Status) SetHttpRequestHeaders(headers [][2]string) Status GetHttpRequestHeader(key string) (string, Status) @@ -80,7 +80,7 @@ type HttpContext interface { ResumeHttpRequest() Status // response - OnHttpResponseHeaders(numHeaders int) Action + OnHttpResponseHeaders(numHeaders int, endOfStream bool) Action GetHttpResponseHeaders() ([][2]string, Status) SetHttpResponseHeaders(headers [][2]string) Status GetHttpResponseHeader(key string) (string, Status) @@ -223,7 +223,7 @@ func (d *DefaultContext) GetUpstreamData(start, maxSize int) ([]byte, Status) { func (d *DefaultContext) OnUpstreamStreamClose(_ PeerType) {} // impl HttpContext -func (d *DefaultContext) OnHttpRequestHeaders(_ int) Action { +func (d *DefaultContext) OnHttpRequestHeaders(_ int, _ bool) Action { return ActionContinue } @@ -308,7 +308,7 @@ func (d *DefaultContext) ResumeHttpRequest() Status { } // impl HttpContext -func (d *DefaultContext) OnHttpResponseHeaders(_ int) Action { +func (d *DefaultContext) OnHttpResponseHeaders(_ int, _ bool) Action { return ActionContinue } From 955cadb9d045e4682d203fe9422cfb45d765c434 Mon Sep 17 00:00:00 2001 From: mathetake Date: Mon, 7 Sep 2020 08:29:16 +0900 Subject: [PATCH 2/2] make ABI aligned with wasm:1.15.0 --- examples/http_auth_random/envoy.yaml | 2 +- examples/http_headers/envoy.yaml | 2 +- examples/http_headers/main.go | 4 ++-- runtime/abi_hostcalls.go | 18 ++++++------------ runtime/abi_types.go | 11 +++++++++++ runtime/context.go | 16 +++++----------- runtime/hostcalls.go | 20 -------------------- 7 files changed, 26 insertions(+), 47 deletions(-) diff --git a/examples/http_auth_random/envoy.yaml b/examples/http_auth_random/envoy.yaml index f267e8b6..cc224f66 100644 --- a/examples/http_auth_random/envoy.yaml +++ b/examples/http_auth_random/envoy.yaml @@ -4,7 +4,7 @@ static_resources: address: socket_address: address: 127.0.0.1 - port_value: 1234 + port_value: 18000 filter_chains: - filters: - name: envoy.http_connection_manager diff --git a/examples/http_headers/envoy.yaml b/examples/http_headers/envoy.yaml index a87e0dc2..01e8ab66 100644 --- a/examples/http_headers/envoy.yaml +++ b/examples/http_headers/envoy.yaml @@ -4,7 +4,7 @@ static_resources: address: socket_address: address: 127.0.0.1 - port_value: 1234 + port_value: 18000 filter_chains: - filters: - name: envoy.http_connection_manager diff --git a/examples/http_headers/main.go b/examples/http_headers/main.go index 4b3b25e1..902123cc 100644 --- a/examples/http_headers/main.go +++ b/examples/http_headers/main.go @@ -21,7 +21,7 @@ func newContext(contextID uint32) runtime.HttpContext { } // override -func (ctx *httpHeaders) OnHttpRequestHeaders(_ int) runtime.Action { +func (ctx *httpHeaders) OnHttpRequestHeaders(_ int, _ bool) runtime.Action { hs, st := ctx.GetHttpRequestHeaders() if st != runtime.StatusOk { runtime.LogCritical("failed to get request headers") @@ -34,7 +34,7 @@ func (ctx *httpHeaders) OnHttpRequestHeaders(_ int) runtime.Action { } // override -func (ctx *httpHeaders) OnHttpResponseHeaders(_ int) runtime.Action { +func (ctx *httpHeaders) OnHttpResponseHeaders(_ int, _ bool) runtime.Action { hs, st := ctx.GetHttpResponseHeaders() if st != runtime.StatusOk { runtime.LogCritical("failed to get request headers") diff --git a/runtime/abi_hostcalls.go b/runtime/abi_hostcalls.go index bd91a999..cbb3f253 100644 --- a/runtime/abi_hostcalls.go +++ b/runtime/abi_hostcalls.go @@ -17,28 +17,16 @@ package runtime //export proxy_log func proxyLog(logLevel LogLevel, messageData *byte, messageSize int) Status -//export proxy_get_configuration -func proxyGetConfiguration(returnBufferData **byte, returnBufferSize *int) Status - //export proxy_set_property func proxySetProperty(pathData *byte, pathSize int, valueData *byte, valueSize int) //export proxy_get_property func proxyGetProperty(pathData *byte, pathSize int, returnValueData **byte, returnValueSize *int) -//export proxy_continue_request -func proxyContinueRequest() Status - -//export proxy_continue_response -func proxyContinueResponse() Status - //export proxy_send_local_response func proxySendLocalResponse(statusCode uint32, statusCodeDetailData *byte, statusCodeDetailsSize int, bodyData *byte, bodySize int, headersData *byte, headersSize int, grpcStatus int32) Status -//export proxy_clear_route_cache -func proxyClearRouteCache() Status - //export proxy_get_shared_data func proxyGetSharedData(keyData *byte, keySize int, returnValueData **byte, returnValueSize *byte, returnCas *uint32) Status @@ -66,6 +54,12 @@ func proxyAddHeaderMapValue(mapType MapType, keyData *byte, keySize int, valueDa //export proxy_replace_header_map_value func proxyReplaceHeaderMapValue(mapType MapType, keyData *byte, keySize int, valueData *byte, valueSize int) Status +//export proxy_continue_stream +func proxyContinueStream(streamType StreamType) Status + +//export proxy_close_stream +func proxyCloseStream(streamType StreamType) Status + //export proxy_remove_header_map_value func proxyRemoveHeaderMapValue(mapType MapType, keyData *byte, keySize int) Status diff --git a/runtime/abi_types.go b/runtime/abi_types.go index 266d8298..31bad415 100644 --- a/runtime/abi_types.go +++ b/runtime/abi_types.go @@ -70,4 +70,15 @@ const ( BufferTypeDownstreamData BufferType = 2 BufferTypeUpstreamData BufferType = 3 BufferTypeHttpCallResponseBody BufferType = 4 + BufferTypeGrpcReceiveBuffer BufferType = 5 + BufferTypeVmConfiguration BufferType = 6 + BufferTypePluginConfiguration BufferType = 7 + BufferTypeCallData BufferType = 8 +) + +type StreamType uint32 + +const ( + StreamTypeRequest StreamType = 0 + StreamTypeResponse StreamType = 1 ) diff --git a/runtime/context.go b/runtime/context.go index 7d907f6a..845449c3 100644 --- a/runtime/context.go +++ b/runtime/context.go @@ -34,7 +34,7 @@ type RootContext interface { Context OnVMStart(vmConfigurationSize int) bool OnConfigure(pluginConfigurationSize int) bool - GetConfiguration() ([]byte, Status) + GetPluginConfiguration(dataSize int) ([]byte, Status) SetTickPeriod(period uint32) Status OnQueueReady(queueID uint32) OnTick() @@ -102,7 +102,6 @@ type HttpContext interface { ResumeHttpResponse() Status SendHttpResponse(statusCode uint32, headers [][2]string, body string) Status - ClearHttpRouteCache() Status OnLog() } @@ -176,8 +175,8 @@ func (d *DefaultContext) OnConfigure(_ int) bool { } // impl RootContext -func (d *DefaultContext) GetConfiguration() ([]byte, Status) { - return getConfiguration() +func (d *DefaultContext) GetPluginConfiguration(dataSize int) ([]byte, Status) { + return getBuffer(BufferTypePluginConfiguration, 0, dataSize) } // impl RootContext @@ -304,7 +303,7 @@ func (d *DefaultContext) AddHttpRequestTrailer(key, value string) Status { // impl HttpContext func (d *DefaultContext) ResumeHttpRequest() Status { - return proxyContinueRequest() + return proxyContinueStream(StreamTypeRequest) } // impl HttpContext @@ -390,15 +389,10 @@ func (d *DefaultContext) AddHttpResponseTrailer(key, value string) Status { // impl HttpContext func (d *DefaultContext) ResumeHttpResponse() Status { - return proxyContinueResponse() + return proxyContinueStream(StreamTypeResponse) } // impl HttpContext func (d *DefaultContext) SendHttpResponse(statusCode uint32, headers [][2]string, body string) Status { return sendHttpResponse(statusCode, headers, body) } - -// impl HttpContext -func (d *DefaultContext) ClearHttpRouteCache() Status { - return proxyClearRouteCache() -} diff --git a/runtime/hostcalls.go b/runtime/hostcalls.go index 83750b67..fa5a1a6b 100644 --- a/runtime/hostcalls.go +++ b/runtime/hostcalls.go @@ -95,26 +95,6 @@ func getBuffer(bufType BufferType, start, maxSize int) ([]byte, Status) { } } -// TODO: not tested yet -func getConfiguration() ([]byte, Status) { - var retData *byte - var retSize int - switch st := proxyGetConfiguration(&retData, &retSize); st { - case StatusOk: - // is this correct handling...? - if retData == nil { - return nil, StatusNotFound - } - return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{ - Data: uintptr(unsafe.Pointer(retData)), - Len: uintptr(retSize), - Cap: uintptr(retSize), - })), st - default: - return nil, st - } -} - func sendHttpResponse(statusCode uint32, headers [][2]string, body string) Status { shs := serializeMap(headers) hp := &shs[0]