libc_uvwasi_wrapper.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "uvwasi.h"
  6. #include "bh_platform.h"
  7. #include "wasm_export.h"
  8. /* clang-format off */
  9. #define get_module_inst(exec_env) \
  10. wasm_runtime_get_module_inst(exec_env)
  11. #define validate_app_addr(offset, size) \
  12. wasm_runtime_validate_app_addr(module_inst, offset, size)
  13. #define validate_native_addr(addr, size) \
  14. wasm_runtime_validate_native_addr(module_inst, addr, size)
  15. #define addr_app_to_native(offset) \
  16. wasm_runtime_addr_app_to_native(module_inst, offset)
  17. #define addr_native_to_app(ptr) \
  18. wasm_runtime_addr_native_to_app(module_inst, ptr)
  19. #define module_malloc(size, p_native_addr) \
  20. wasm_runtime_module_malloc(module_inst, size, p_native_addr)
  21. #define module_free(offset) \
  22. wasm_runtime_module_free(module_inst, offset)
  23. /* clang-format on */
  24. #define wasi_errno_t uvwasi_errno_t
  25. #define wasi_fd_t uvwasi_fd_t
  26. #define wasi_clockid_t uvwasi_clockid_t
  27. #define wasi_timestamp_t uvwasi_timestamp_t
  28. #define wasi_filesize_t uvwasi_filesize_t
  29. #define wasi_prestat_app_t uvwasi_prestat_app_t
  30. #define wasi_filedelta_t uvwasi_filedelta_t
  31. #define wasi_whence_t uvwasi_whence_t
  32. #define wasi_fdflags_t uvwasi_fdflags_t
  33. #define wasi_rights_t uvwasi_rights_t
  34. #define wasi_advice_t uvwasi_advice_t
  35. #define wasi_lookupflags_t uvwasi_lookupflags_t
  36. #define wasi_preopentype_t uvwasi_preopentype_t
  37. #define wasi_fdstat_t uvwasi_fdstat_t
  38. #define wasi_oflags_t uvwasi_oflags_t
  39. #define wasi_dircookie_t uvwasi_dircookie_t
  40. #define wasi_filestat_t uvwasi_filestat_t
  41. #define wasi_fstflags_t uvwasi_fstflags_t
  42. #define wasi_subscription_t uvwasi_subscription_t
  43. #define wasi_event_t uvwasi_event_t
  44. #define wasi_exitcode_t uvwasi_exitcode_t
  45. #define wasi_signal_t uvwasi_signal_t
  46. #define wasi_riflags_t uvwasi_riflags_t
  47. #define wasi_roflags_t uvwasi_roflags_t
  48. #define wasi_siflags_t uvwasi_siflags_t
  49. #define wasi_sdflags_t uvwasi_sdflags_t
  50. #define wasi_iovec_t uvwasi_iovec_t
  51. #define wasi_ciovec_t uvwasi_ciovec_t
  52. typedef struct wasi_prestat_app {
  53. wasi_preopentype_t pr_type;
  54. uint32 pr_name_len;
  55. } wasi_prestat_app_t;
  56. typedef struct iovec_app {
  57. uint32 buf_offset;
  58. uint32 buf_len;
  59. } iovec_app_t;
  60. typedef struct WASIContext {
  61. uvwasi_t uvwasi;
  62. uint32_t exit_code;
  63. } WASIContext;
  64. void *
  65. wasm_runtime_get_wasi_ctx(wasm_module_inst_t module_inst);
  66. static uvwasi_t *
  67. get_wasi_ctx(wasm_module_inst_t module_inst)
  68. {
  69. WASIContext *ctx = wasm_runtime_get_wasi_ctx(module_inst);
  70. if (ctx == NULL) {
  71. return NULL;
  72. }
  73. return &ctx->uvwasi;
  74. }
  75. static wasi_errno_t
  76. wasi_args_get(wasm_exec_env_t exec_env, uint32 *argv_offsets, char *argv_buf)
  77. {
  78. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  79. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  80. uvwasi_size_t argc, argv_buf_size, i;
  81. char **argv;
  82. uint64 total_size;
  83. wasi_errno_t err;
  84. if (!uvwasi)
  85. return (wasi_errno_t)-1;
  86. err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size);
  87. if (err)
  88. return err;
  89. total_size = sizeof(int32) * ((uint64)argc + 1);
  90. if (total_size >= UINT32_MAX
  91. || !validate_native_addr(argv_offsets, (uint32)total_size)
  92. || argv_buf_size >= UINT32_MAX
  93. || !validate_native_addr(argv_buf, (uint32)argv_buf_size))
  94. return (wasi_errno_t)-1;
  95. total_size = sizeof(char *) * ((uint64)argc + 1);
  96. if (total_size >= UINT32_MAX
  97. || !(argv = wasm_runtime_malloc((uint32)total_size)))
  98. return (wasi_errno_t)-1;
  99. err = uvwasi_args_get(uvwasi, argv, argv_buf);
  100. if (err) {
  101. wasm_runtime_free(argv);
  102. return err;
  103. }
  104. for (i = 0; i < argc; i++)
  105. argv_offsets[i] = addr_native_to_app(argv[i]);
  106. wasm_runtime_free(argv);
  107. return 0;
  108. }
  109. static wasi_errno_t
  110. wasi_args_sizes_get(wasm_exec_env_t exec_env, uint32 *argc_app,
  111. uint32 *argv_buf_size_app)
  112. {
  113. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  114. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  115. uvwasi_size_t argc, argv_buf_size;
  116. wasi_errno_t err;
  117. if (!uvwasi)
  118. return (wasi_errno_t)-1;
  119. if (!validate_native_addr(argc_app, sizeof(uint32))
  120. || !validate_native_addr(argv_buf_size_app, sizeof(uint32)))
  121. return (wasi_errno_t)-1;
  122. err = uvwasi_args_sizes_get(uvwasi, &argc, &argv_buf_size);
  123. if (err)
  124. return err;
  125. *argc_app = (uint32)argc;
  126. *argv_buf_size_app = (uint32)argv_buf_size;
  127. return 0;
  128. }
  129. static wasi_errno_t
  130. wasi_clock_res_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
  131. wasi_timestamp_t *resolution)
  132. {
  133. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  134. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  135. if (!validate_native_addr(resolution, sizeof(wasi_timestamp_t)))
  136. return (wasi_errno_t)-1;
  137. return uvwasi_clock_res_get(uvwasi, clock_id, resolution);
  138. }
  139. static wasi_errno_t
  140. wasi_clock_time_get(wasm_exec_env_t exec_env, wasi_clockid_t clock_id,
  141. wasi_timestamp_t precision, wasi_timestamp_t *time)
  142. {
  143. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  144. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  145. if (!validate_native_addr(time, sizeof(wasi_timestamp_t)))
  146. return (wasi_errno_t)-1;
  147. return uvwasi_clock_time_get(uvwasi, clock_id, precision, time);
  148. }
  149. static wasi_errno_t
  150. wasi_environ_get(wasm_exec_env_t exec_env, uint32 *environ_offsets,
  151. char *environ_buf)
  152. {
  153. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  154. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  155. uvwasi_size_t environ_count, environ_buf_size, i;
  156. uint64 total_size;
  157. char **environs;
  158. wasi_errno_t err;
  159. if (!uvwasi)
  160. return (wasi_errno_t)-1;
  161. err = uvwasi_environ_sizes_get(uvwasi, &environ_count, &environ_buf_size);
  162. if (err)
  163. return err;
  164. if (environ_count == 0)
  165. return 0;
  166. total_size = sizeof(int32) * ((uint64)environ_count + 1);
  167. if (total_size >= UINT32_MAX
  168. || !validate_native_addr(environ_offsets, (uint32)total_size)
  169. || environ_buf_size >= UINT32_MAX
  170. || !validate_native_addr(environ_buf, (uint32)environ_buf_size))
  171. return (wasi_errno_t)-1;
  172. total_size = sizeof(char *) * (((uint64)environ_count + 1));
  173. if (total_size >= UINT32_MAX
  174. || !(environs = wasm_runtime_malloc((uint32)total_size)))
  175. return (wasi_errno_t)-1;
  176. err = uvwasi_environ_get(uvwasi, environs, environ_buf);
  177. if (err) {
  178. wasm_runtime_free(environs);
  179. return err;
  180. }
  181. for (i = 0; i < environ_count; i++)
  182. environ_offsets[i] = addr_native_to_app(environs[i]);
  183. wasm_runtime_free(environs);
  184. return 0;
  185. }
  186. static wasi_errno_t
  187. wasi_environ_sizes_get(wasm_exec_env_t exec_env, uint32 *environ_count_app,
  188. uint32 *environ_buf_size_app)
  189. {
  190. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  191. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  192. uvwasi_size_t environ_count, environ_buf_size;
  193. wasi_errno_t err;
  194. if (!uvwasi)
  195. return (wasi_errno_t)-1;
  196. if (!validate_native_addr(environ_count_app, sizeof(uint32))
  197. || !validate_native_addr(environ_buf_size_app, sizeof(uint32)))
  198. return (wasi_errno_t)-1;
  199. err = uvwasi_environ_sizes_get(uvwasi, &environ_count, &environ_buf_size);
  200. if (err)
  201. return err;
  202. *environ_count_app = (uint32)environ_count;
  203. *environ_buf_size_app = (uint32)environ_buf_size;
  204. return 0;
  205. }
  206. static wasi_errno_t
  207. wasi_fd_prestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  208. wasi_prestat_app_t *prestat_app)
  209. {
  210. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  211. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  212. uvwasi_prestat_t prestat;
  213. wasi_errno_t err;
  214. if (!uvwasi)
  215. return (wasi_errno_t)-1;
  216. if (!validate_native_addr(prestat_app, sizeof(wasi_prestat_app_t)))
  217. return (wasi_errno_t)-1;
  218. err = uvwasi_fd_prestat_get(uvwasi, fd, &prestat);
  219. if (err)
  220. return err;
  221. prestat_app->pr_type = prestat.pr_type;
  222. prestat_app->pr_name_len = (uint32)prestat.u.dir.pr_name_len;
  223. return 0;
  224. }
  225. static wasi_errno_t
  226. wasi_fd_prestat_dir_name(wasm_exec_env_t exec_env, wasi_fd_t fd, char *path,
  227. uint32 path_len)
  228. {
  229. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  230. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  231. if (!uvwasi)
  232. return (wasi_errno_t)-1;
  233. return uvwasi_fd_prestat_dir_name(uvwasi, fd, path, path_len);
  234. }
  235. static wasi_errno_t
  236. wasi_fd_close(wasm_exec_env_t exec_env, wasi_fd_t fd)
  237. {
  238. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  239. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  240. if (!uvwasi)
  241. return (wasi_errno_t)-1;
  242. return uvwasi_fd_close(uvwasi, fd);
  243. }
  244. static wasi_errno_t
  245. wasi_fd_datasync(wasm_exec_env_t exec_env, wasi_fd_t fd)
  246. {
  247. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  248. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  249. if (!uvwasi)
  250. return (wasi_errno_t)-1;
  251. return uvwasi_fd_datasync(uvwasi, fd);
  252. }
  253. static wasi_errno_t
  254. wasi_fd_pread(wasm_exec_env_t exec_env, wasi_fd_t fd, iovec_app_t *iovec_app,
  255. uint32 iovs_len, wasi_filesize_t offset, uint32 *nread_app)
  256. {
  257. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  258. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  259. wasi_iovec_t *iovec, *iovec_begin;
  260. uint64 total_size;
  261. uvwasi_size_t nread;
  262. uint32 i;
  263. wasi_errno_t err;
  264. if (!uvwasi)
  265. return (wasi_errno_t)-1;
  266. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  267. if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
  268. || total_size >= UINT32_MAX
  269. || !validate_native_addr(iovec_app, (uint32)total_size))
  270. return (wasi_errno_t)-1;
  271. total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
  272. if (total_size >= UINT32_MAX
  273. || !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
  274. return (wasi_errno_t)-1;
  275. iovec = iovec_begin;
  276. for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) {
  277. if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
  278. err = (wasi_errno_t)-1;
  279. goto fail;
  280. }
  281. iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
  282. iovec->buf_len = iovec_app->buf_len;
  283. }
  284. err = uvwasi_fd_pread(uvwasi, fd, iovec_begin, iovs_len, offset, &nread);
  285. if (err)
  286. goto fail;
  287. *nread_app = (uint32)nread;
  288. /* success */
  289. err = 0;
  290. fail:
  291. wasm_runtime_free(iovec_begin);
  292. return err;
  293. }
  294. static wasi_errno_t
  295. wasi_fd_pwrite(wasm_exec_env_t exec_env, wasi_fd_t fd,
  296. const iovec_app_t *iovec_app, uint32 iovs_len,
  297. wasi_filesize_t offset, uint32 *nwritten_app)
  298. {
  299. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  300. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  301. wasi_ciovec_t *ciovec, *ciovec_begin;
  302. uint64 total_size;
  303. uvwasi_size_t nwritten;
  304. uint32 i;
  305. wasi_errno_t err;
  306. if (!uvwasi)
  307. return (wasi_errno_t)-1;
  308. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  309. if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
  310. || total_size >= UINT32_MAX
  311. || !validate_native_addr((void *)iovec_app, (uint32)total_size))
  312. return (wasi_errno_t)-1;
  313. total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
  314. if (total_size >= UINT32_MAX
  315. || !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
  316. return (wasi_errno_t)-1;
  317. ciovec = ciovec_begin;
  318. for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) {
  319. if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
  320. err = (wasi_errno_t)-1;
  321. goto fail;
  322. }
  323. ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
  324. ciovec->buf_len = iovec_app->buf_len;
  325. }
  326. err =
  327. uvwasi_fd_pwrite(uvwasi, fd, ciovec_begin, iovs_len, offset, &nwritten);
  328. if (err)
  329. goto fail;
  330. *nwritten_app = (uint32)nwritten;
  331. /* success */
  332. err = 0;
  333. fail:
  334. wasm_runtime_free(ciovec_begin);
  335. return err;
  336. }
  337. static wasi_errno_t
  338. wasi_fd_read(wasm_exec_env_t exec_env, wasi_fd_t fd,
  339. const iovec_app_t *iovec_app, uint32 iovs_len, uint32 *nread_app)
  340. {
  341. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  342. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  343. wasi_iovec_t *iovec, *iovec_begin;
  344. uint64 total_size;
  345. uvwasi_size_t nread;
  346. uint32 i;
  347. wasi_errno_t err;
  348. if (!uvwasi)
  349. return (wasi_errno_t)-1;
  350. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  351. if (!validate_native_addr(nread_app, (uint32)sizeof(uint32))
  352. || total_size >= UINT32_MAX
  353. || !validate_native_addr((void *)iovec_app, (uint32)total_size))
  354. return (wasi_errno_t)-1;
  355. total_size = sizeof(wasi_iovec_t) * (uint64)iovs_len;
  356. if (total_size >= UINT32_MAX
  357. || !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
  358. return (wasi_errno_t)-1;
  359. iovec = iovec_begin;
  360. for (i = 0; i < iovs_len; i++, iovec_app++, iovec++) {
  361. if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
  362. err = (wasi_errno_t)-1;
  363. goto fail;
  364. }
  365. iovec->buf = (void *)addr_app_to_native(iovec_app->buf_offset);
  366. iovec->buf_len = iovec_app->buf_len;
  367. }
  368. err = uvwasi_fd_read(uvwasi, fd, iovec_begin, iovs_len, &nread);
  369. if (err)
  370. goto fail;
  371. *nread_app = (uint32)nread;
  372. /* success */
  373. err = 0;
  374. fail:
  375. wasm_runtime_free(iovec_begin);
  376. return err;
  377. }
  378. static wasi_errno_t
  379. wasi_fd_renumber(wasm_exec_env_t exec_env, wasi_fd_t from, wasi_fd_t to)
  380. {
  381. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  382. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  383. if (!uvwasi)
  384. return (wasi_errno_t)-1;
  385. return uvwasi_fd_renumber(uvwasi, from, to);
  386. }
  387. static wasi_errno_t
  388. wasi_fd_seek(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filedelta_t offset,
  389. wasi_whence_t whence, wasi_filesize_t *newoffset)
  390. {
  391. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  392. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  393. if (!uvwasi)
  394. return (wasi_errno_t)-1;
  395. if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
  396. return (wasi_errno_t)-1;
  397. return uvwasi_fd_seek(uvwasi, fd, offset, whence, newoffset);
  398. }
  399. static wasi_errno_t
  400. wasi_fd_tell(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t *newoffset)
  401. {
  402. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  403. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  404. if (!uvwasi)
  405. return (wasi_errno_t)-1;
  406. if (!validate_native_addr(newoffset, sizeof(wasi_filesize_t)))
  407. return (wasi_errno_t)-1;
  408. return uvwasi_fd_tell(uvwasi, fd, newoffset);
  409. }
  410. static wasi_errno_t
  411. wasi_fd_fdstat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  412. wasi_fdstat_t *fdstat_app)
  413. {
  414. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  415. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  416. wasi_fdstat_t fdstat;
  417. wasi_errno_t err;
  418. if (!uvwasi)
  419. return (wasi_errno_t)-1;
  420. if (!validate_native_addr(fdstat_app, sizeof(wasi_fdstat_t)))
  421. return (wasi_errno_t)-1;
  422. err = uvwasi_fd_fdstat_get(uvwasi, fd, &fdstat);
  423. if (err)
  424. return err;
  425. memcpy(fdstat_app, &fdstat, sizeof(wasi_fdstat_t));
  426. return 0;
  427. }
  428. static wasi_errno_t
  429. wasi_fd_fdstat_set_flags(wasm_exec_env_t exec_env, wasi_fd_t fd,
  430. wasi_fdflags_t flags)
  431. {
  432. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  433. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  434. if (!uvwasi)
  435. return (wasi_errno_t)-1;
  436. return uvwasi_fd_fdstat_set_flags(uvwasi, fd, flags);
  437. }
  438. static wasi_errno_t
  439. wasi_fd_fdstat_set_rights(wasm_exec_env_t exec_env, wasi_fd_t fd,
  440. wasi_rights_t fs_rights_base,
  441. wasi_rights_t fs_rights_inheriting)
  442. {
  443. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  444. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  445. if (!uvwasi)
  446. return (wasi_errno_t)-1;
  447. return uvwasi_fd_fdstat_set_rights(uvwasi, fd, fs_rights_base,
  448. fs_rights_inheriting);
  449. }
  450. static wasi_errno_t
  451. wasi_fd_sync(wasm_exec_env_t exec_env, wasi_fd_t fd)
  452. {
  453. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  454. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  455. if (!uvwasi)
  456. return (wasi_errno_t)-1;
  457. return uvwasi_fd_sync(uvwasi, fd);
  458. }
  459. static wasi_errno_t
  460. wasi_fd_write(wasm_exec_env_t exec_env, wasi_fd_t fd,
  461. const iovec_app_t *iovec_app, uint32 iovs_len,
  462. uint32 *nwritten_app)
  463. {
  464. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  465. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  466. wasi_ciovec_t *ciovec, *ciovec_begin;
  467. uint64 total_size;
  468. uvwasi_size_t nwritten;
  469. uint32 i;
  470. wasi_errno_t err;
  471. if (!uvwasi)
  472. return (wasi_errno_t)-1;
  473. total_size = sizeof(iovec_app_t) * (uint64)iovs_len;
  474. if (!validate_native_addr(nwritten_app, (uint32)sizeof(uint32))
  475. || total_size >= UINT32_MAX
  476. || !validate_native_addr((void *)iovec_app, (uint32)total_size))
  477. return (wasi_errno_t)-1;
  478. total_size = sizeof(wasi_ciovec_t) * (uint64)iovs_len;
  479. if (total_size >= UINT32_MAX
  480. || !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
  481. return (wasi_errno_t)-1;
  482. ciovec = ciovec_begin;
  483. for (i = 0; i < iovs_len; i++, iovec_app++, ciovec++) {
  484. if (!validate_app_addr(iovec_app->buf_offset, iovec_app->buf_len)) {
  485. err = (wasi_errno_t)-1;
  486. goto fail;
  487. }
  488. ciovec->buf = (char *)addr_app_to_native(iovec_app->buf_offset);
  489. ciovec->buf_len = iovec_app->buf_len;
  490. }
  491. #ifndef BH_VPRINTF
  492. err = uvwasi_fd_write(uvwasi, fd, ciovec_begin, iovs_len, &nwritten);
  493. #else
  494. /* redirect stdout/stderr output to BH_VPRINTF function */
  495. if (fd == 1 || fd == 2) {
  496. int i;
  497. const struct iovec *iov1 = (const struct iovec *)ciovec_begin;
  498. nwritten = 0;
  499. for (i = 0; i < (int)iovs_len; i++, iov1++) {
  500. if (iov1->iov_len > 0 && iov1->iov_base) {
  501. char format[16];
  502. /* make up format string "%.ns" */
  503. snprintf(format, sizeof(format), "%%.%ds", (int)iov1->iov_len);
  504. nwritten += (uvwasi_size_t)os_printf(format, iov1->iov_base);
  505. }
  506. }
  507. err = 0;
  508. }
  509. else {
  510. err = uvwasi_fd_write(uvwasi, fd, ciovec_begin, iovs_len, &nwritten);
  511. }
  512. #endif /* end of BH_VPRINTF */
  513. if (err)
  514. goto fail;
  515. *nwritten_app = (uint32)nwritten;
  516. /* success */
  517. err = 0;
  518. fail:
  519. wasm_runtime_free(ciovec_begin);
  520. return err;
  521. }
  522. static wasi_errno_t
  523. wasi_fd_advise(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
  524. wasi_filesize_t len, wasi_advice_t advice)
  525. {
  526. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  527. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  528. if (!uvwasi)
  529. return (wasi_errno_t)-1;
  530. return uvwasi_fd_advise(uvwasi, fd, offset, len, advice);
  531. }
  532. static wasi_errno_t
  533. wasi_fd_allocate(wasm_exec_env_t exec_env, wasi_fd_t fd, wasi_filesize_t offset,
  534. wasi_filesize_t len)
  535. {
  536. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  537. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  538. if (!uvwasi)
  539. return (wasi_errno_t)-1;
  540. return uvwasi_fd_allocate(uvwasi, fd, offset, len);
  541. }
  542. static wasi_errno_t
  543. wasi_path_create_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
  544. const char *path, uint32 path_len)
  545. {
  546. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  547. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  548. if (!uvwasi)
  549. return (wasi_errno_t)-1;
  550. return uvwasi_path_create_directory(uvwasi, fd, path, path_len);
  551. }
  552. static wasi_errno_t
  553. wasi_path_link(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
  554. wasi_lookupflags_t old_flags, const char *old_path,
  555. uint32 old_path_len, wasi_fd_t new_fd, const char *new_path,
  556. uint32 new_path_len)
  557. {
  558. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  559. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  560. if (!uvwasi)
  561. return (wasi_errno_t)-1;
  562. return uvwasi_path_link(uvwasi, old_fd, old_flags, old_path, old_path_len,
  563. new_fd, new_path, new_path_len);
  564. }
  565. static wasi_errno_t
  566. wasi_path_open(wasm_exec_env_t exec_env, wasi_fd_t dirfd,
  567. wasi_lookupflags_t dirflags, const char *path, uint32 path_len,
  568. wasi_oflags_t oflags, wasi_rights_t fs_rights_base,
  569. wasi_rights_t fs_rights_inheriting, wasi_fdflags_t fs_flags,
  570. wasi_fd_t *fd_app)
  571. {
  572. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  573. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  574. wasi_fd_t fd = (wasi_fd_t)-1; /* set fd_app -1 if path open failed */
  575. wasi_errno_t err;
  576. if (!uvwasi)
  577. return (wasi_errno_t)-1;
  578. if (!validate_native_addr(fd_app, sizeof(wasi_fd_t)))
  579. return (wasi_errno_t)-1;
  580. err = uvwasi_path_open(uvwasi, dirfd, dirflags, path, path_len, oflags,
  581. fs_rights_base, fs_rights_inheriting, fs_flags, &fd);
  582. *fd_app = fd;
  583. return err;
  584. }
  585. static wasi_errno_t
  586. wasi_fd_readdir(wasm_exec_env_t exec_env, wasi_fd_t fd, void *buf,
  587. uint32 buf_len, wasi_dircookie_t cookie, uint32 *bufused_app)
  588. {
  589. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  590. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  591. uvwasi_size_t bufused;
  592. wasi_errno_t err;
  593. if (!uvwasi)
  594. return (wasi_errno_t)-1;
  595. if (!validate_native_addr(bufused_app, sizeof(uint32)))
  596. return (wasi_errno_t)-1;
  597. err = uvwasi_fd_readdir(uvwasi, fd, buf, buf_len, cookie, &bufused);
  598. if (err)
  599. return err;
  600. *bufused_app = (uint32)bufused;
  601. return 0;
  602. }
  603. static wasi_errno_t
  604. wasi_path_readlink(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
  605. uint32 path_len, char *buf, uint32 buf_len,
  606. uint32 *bufused_app)
  607. {
  608. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  609. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  610. uvwasi_size_t bufused;
  611. wasi_errno_t err;
  612. if (!uvwasi)
  613. return (wasi_errno_t)-1;
  614. if (!validate_native_addr(bufused_app, sizeof(uint32)))
  615. return (wasi_errno_t)-1;
  616. err = uvwasi_path_readlink(uvwasi, fd, path, path_len, buf, buf_len,
  617. &bufused);
  618. if (err)
  619. return err;
  620. *bufused_app = (uint32)bufused;
  621. return 0;
  622. }
  623. static wasi_errno_t
  624. wasi_path_rename(wasm_exec_env_t exec_env, wasi_fd_t old_fd,
  625. const char *old_path, uint32 old_path_len, wasi_fd_t new_fd,
  626. const char *new_path, uint32 new_path_len)
  627. {
  628. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  629. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  630. if (!uvwasi)
  631. return (wasi_errno_t)-1;
  632. return uvwasi_path_rename(uvwasi, old_fd, old_path, old_path_len, new_fd,
  633. new_path, new_path_len);
  634. }
  635. static wasi_errno_t
  636. wasi_fd_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  637. wasi_filestat_t *filestat)
  638. {
  639. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  640. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  641. if (!uvwasi)
  642. return (wasi_errno_t)-1;
  643. if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
  644. return (wasi_errno_t)-1;
  645. return uvwasi_fd_filestat_get(uvwasi, fd, filestat);
  646. }
  647. static wasi_errno_t
  648. wasi_fd_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
  649. wasi_timestamp_t st_atim, wasi_timestamp_t st_mtim,
  650. wasi_fstflags_t fstflags)
  651. {
  652. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  653. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  654. if (!uvwasi)
  655. return (wasi_errno_t)-1;
  656. return uvwasi_fd_filestat_set_times(uvwasi, fd, st_atim, st_mtim, fstflags);
  657. }
  658. static wasi_errno_t
  659. wasi_fd_filestat_set_size(wasm_exec_env_t exec_env, wasi_fd_t fd,
  660. wasi_filesize_t st_size)
  661. {
  662. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  663. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  664. if (!uvwasi)
  665. return (wasi_errno_t)-1;
  666. return uvwasi_fd_filestat_set_size(uvwasi, fd, st_size);
  667. }
  668. static wasi_errno_t
  669. wasi_path_filestat_get(wasm_exec_env_t exec_env, wasi_fd_t fd,
  670. wasi_lookupflags_t flags, const char *path,
  671. uint32 path_len, wasi_filestat_t *filestat)
  672. {
  673. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  674. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  675. if (!uvwasi)
  676. return (wasi_errno_t)-1;
  677. if (!validate_native_addr(filestat, sizeof(wasi_filestat_t)))
  678. return (wasi_errno_t)-1;
  679. return uvwasi_path_filestat_get(uvwasi, fd, flags, path, path_len,
  680. filestat);
  681. }
  682. static wasi_errno_t
  683. wasi_path_filestat_set_times(wasm_exec_env_t exec_env, wasi_fd_t fd,
  684. wasi_lookupflags_t flags, const char *path,
  685. uint32 path_len, wasi_timestamp_t st_atim,
  686. wasi_timestamp_t st_mtim, wasi_fstflags_t fstflags)
  687. {
  688. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  689. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  690. if (!uvwasi)
  691. return (wasi_errno_t)-1;
  692. return uvwasi_path_filestat_set_times(uvwasi, fd, flags, path, path_len,
  693. st_atim, st_mtim, fstflags);
  694. }
  695. static wasi_errno_t
  696. wasi_path_symlink(wasm_exec_env_t exec_env, const char *old_path,
  697. uint32 old_path_len, wasi_fd_t fd, const char *new_path,
  698. uint32 new_path_len)
  699. {
  700. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  701. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  702. if (!uvwasi)
  703. return (wasi_errno_t)-1;
  704. return uvwasi_path_symlink(uvwasi, old_path, old_path_len, fd, new_path,
  705. new_path_len);
  706. }
  707. static wasi_errno_t
  708. wasi_path_unlink_file(wasm_exec_env_t exec_env, wasi_fd_t fd, const char *path,
  709. uint32 path_len)
  710. {
  711. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  712. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  713. if (!uvwasi)
  714. return (wasi_errno_t)-1;
  715. return uvwasi_path_unlink_file(uvwasi, fd, path, path_len);
  716. }
  717. static wasi_errno_t
  718. wasi_path_remove_directory(wasm_exec_env_t exec_env, wasi_fd_t fd,
  719. const char *path, uint32 path_len)
  720. {
  721. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  722. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  723. if (!uvwasi)
  724. return (wasi_errno_t)-1;
  725. return uvwasi_path_remove_directory(uvwasi, fd, path, path_len);
  726. }
  727. static wasi_errno_t
  728. wasi_poll_oneoff(wasm_exec_env_t exec_env, const wasi_subscription_t *in,
  729. wasi_event_t *out, uint32 nsubscriptions, uint32 *nevents_app)
  730. {
  731. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  732. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  733. uvwasi_size_t nevents;
  734. wasi_errno_t err;
  735. if (!uvwasi)
  736. return (wasi_errno_t)-1;
  737. if (!validate_native_addr((void *)in, sizeof(wasi_subscription_t))
  738. || !validate_native_addr(out, sizeof(wasi_event_t))
  739. || !validate_native_addr(nevents_app, sizeof(uint32)))
  740. return (wasi_errno_t)-1;
  741. err = uvwasi_poll_oneoff(uvwasi, in, out, nsubscriptions, &nevents);
  742. if (err)
  743. return err;
  744. *nevents_app = (uint32)nevents;
  745. return 0;
  746. }
  747. static void
  748. wasi_proc_exit(wasm_exec_env_t exec_env, wasi_exitcode_t rval)
  749. {
  750. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  751. WASIContext *wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
  752. /* Here throwing exception is just to let wasm app exit,
  753. the upper layer should clear the exception and return
  754. as normal */
  755. wasm_runtime_set_exception(module_inst, "wasi proc exit");
  756. wasi_ctx->exit_code = rval;
  757. }
  758. static wasi_errno_t
  759. wasi_proc_raise(wasm_exec_env_t exec_env, wasi_signal_t sig)
  760. {
  761. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  762. char buf[32];
  763. snprintf(buf, sizeof(buf), "%s%d", "wasi proc raise ", sig);
  764. wasm_runtime_set_exception(module_inst, buf);
  765. return 0;
  766. }
  767. static wasi_errno_t
  768. wasi_random_get(wasm_exec_env_t exec_env, void *buf, uint32 buf_len)
  769. {
  770. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  771. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  772. return uvwasi_random_get(uvwasi, buf, buf_len);
  773. }
  774. static wasi_errno_t
  775. wasi_sock_recv(wasm_exec_env_t exec_env, wasi_fd_t sock, iovec_app_t *ri_data,
  776. uint32 ri_data_len, wasi_riflags_t ri_flags,
  777. uint32 *ro_datalen_app, wasi_roflags_t *ro_flags)
  778. {
  779. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  780. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  781. wasi_iovec_t *iovec, *iovec_begin;
  782. uint64 total_size;
  783. uvwasi_size_t ro_datalen;
  784. uint32 i;
  785. wasi_errno_t err;
  786. if (!uvwasi)
  787. return (wasi_errno_t)-1;
  788. total_size = sizeof(iovec_app_t) * (uint64)ri_data_len;
  789. if (!validate_native_addr(ro_datalen_app, (uint32)sizeof(uint32))
  790. || !validate_native_addr(ro_flags, (uint32)sizeof(wasi_roflags_t))
  791. || total_size >= UINT32_MAX
  792. || !validate_native_addr(ri_data, (uint32)total_size))
  793. return (wasi_errno_t)-1;
  794. total_size = sizeof(wasi_iovec_t) * (uint64)ri_data_len;
  795. if (total_size >= UINT32_MAX
  796. || !(iovec_begin = wasm_runtime_malloc((uint32)total_size)))
  797. return (wasi_errno_t)-1;
  798. iovec = iovec_begin;
  799. for (i = 0; i < ri_data_len; i++, ri_data++, iovec++) {
  800. if (!validate_app_addr(ri_data->buf_offset, ri_data->buf_len)) {
  801. err = (wasi_errno_t)-1;
  802. goto fail;
  803. }
  804. iovec->buf = (void *)addr_app_to_native(ri_data->buf_offset);
  805. iovec->buf_len = ri_data->buf_len;
  806. }
  807. err = uvwasi_sock_recv(uvwasi, sock, iovec_begin, ri_data_len, ri_flags,
  808. &ro_datalen, ro_flags);
  809. if (err)
  810. goto fail;
  811. *(uint32 *)ro_datalen_app = (uint32)ro_datalen;
  812. /* success */
  813. err = 0;
  814. fail:
  815. wasm_runtime_free(iovec_begin);
  816. return err;
  817. }
  818. static wasi_errno_t
  819. wasi_sock_send(wasm_exec_env_t exec_env, wasi_fd_t sock,
  820. const iovec_app_t *si_data, uint32 si_data_len,
  821. wasi_siflags_t si_flags, uint32 *so_datalen_app)
  822. {
  823. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  824. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  825. wasi_ciovec_t *ciovec, *ciovec_begin;
  826. uint64 total_size;
  827. uvwasi_size_t so_datalen;
  828. uint32 i;
  829. wasi_errno_t err;
  830. if (!uvwasi)
  831. return (wasi_errno_t)-1;
  832. total_size = sizeof(iovec_app_t) * (uint64)si_data_len;
  833. if (!validate_native_addr(so_datalen_app, sizeof(uint32))
  834. || total_size >= UINT32_MAX
  835. || !validate_native_addr((void *)si_data, (uint32)total_size))
  836. return (wasi_errno_t)-1;
  837. total_size = sizeof(wasi_ciovec_t) * (uint64)si_data_len;
  838. if (total_size >= UINT32_MAX
  839. || !(ciovec_begin = wasm_runtime_malloc((uint32)total_size)))
  840. return (wasi_errno_t)-1;
  841. ciovec = ciovec_begin;
  842. for (i = 0; i < si_data_len; i++, si_data++, ciovec++) {
  843. if (!validate_app_addr(si_data->buf_offset, si_data->buf_len)) {
  844. err = (wasi_errno_t)-1;
  845. goto fail;
  846. }
  847. ciovec->buf = (char *)addr_app_to_native(si_data->buf_offset);
  848. ciovec->buf_len = si_data->buf_len;
  849. }
  850. err = uvwasi_sock_send(uvwasi, sock, ciovec_begin, si_data_len, si_flags,
  851. &so_datalen);
  852. if (err)
  853. goto fail;
  854. *so_datalen_app = (uint32)so_datalen;
  855. /* success */
  856. err = 0;
  857. fail:
  858. wasm_runtime_free(ciovec_begin);
  859. return err;
  860. }
  861. static wasi_errno_t
  862. wasi_sock_shutdown(wasm_exec_env_t exec_env, wasi_fd_t sock, wasi_sdflags_t how)
  863. {
  864. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  865. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  866. if (!uvwasi)
  867. return (wasi_errno_t)-1;
  868. return uvwasi_sock_shutdown(uvwasi, sock, how);
  869. }
  870. static wasi_errno_t
  871. wasi_sched_yield(wasm_exec_env_t exec_env)
  872. {
  873. wasm_module_inst_t module_inst = get_module_inst(exec_env);
  874. uvwasi_t *uvwasi = get_wasi_ctx(module_inst);
  875. return uvwasi_sched_yield(uvwasi);
  876. }
  877. /* clang-format off */
  878. #define REG_NATIVE_FUNC(func_name, signature) \
  879. { #func_name, wasi_##func_name, signature, NULL }
  880. /* clang-format on */
  881. static NativeSymbol native_symbols_libc_wasi[] = {
  882. REG_NATIVE_FUNC(args_get, "(**)i"),
  883. REG_NATIVE_FUNC(args_sizes_get, "(**)i"),
  884. REG_NATIVE_FUNC(clock_res_get, "(i*)i"),
  885. REG_NATIVE_FUNC(clock_time_get, "(iI*)i"),
  886. REG_NATIVE_FUNC(environ_get, "(**)i"),
  887. REG_NATIVE_FUNC(environ_sizes_get, "(**)i"),
  888. REG_NATIVE_FUNC(fd_prestat_get, "(i*)i"),
  889. REG_NATIVE_FUNC(fd_prestat_dir_name, "(i*~)i"),
  890. REG_NATIVE_FUNC(fd_close, "(i)i"),
  891. REG_NATIVE_FUNC(fd_datasync, "(i)i"),
  892. REG_NATIVE_FUNC(fd_pread, "(i*iI*)i"),
  893. REG_NATIVE_FUNC(fd_pwrite, "(i*iI*)i"),
  894. REG_NATIVE_FUNC(fd_read, "(i*i*)i"),
  895. REG_NATIVE_FUNC(fd_renumber, "(ii)i"),
  896. REG_NATIVE_FUNC(fd_seek, "(iIi*)i"),
  897. REG_NATIVE_FUNC(fd_tell, "(i*)i"),
  898. REG_NATIVE_FUNC(fd_fdstat_get, "(i*)i"),
  899. REG_NATIVE_FUNC(fd_fdstat_set_flags, "(ii)i"),
  900. REG_NATIVE_FUNC(fd_fdstat_set_rights, "(iII)i"),
  901. REG_NATIVE_FUNC(fd_sync, "(i)i"),
  902. REG_NATIVE_FUNC(fd_write, "(i*i*)i"),
  903. REG_NATIVE_FUNC(fd_advise, "(iIIi)i"),
  904. REG_NATIVE_FUNC(fd_allocate, "(iII)i"),
  905. REG_NATIVE_FUNC(path_create_directory, "(i*~)i"),
  906. REG_NATIVE_FUNC(path_link, "(ii*~i*~)i"),
  907. REG_NATIVE_FUNC(path_open, "(ii*~iIIi*)i"),
  908. REG_NATIVE_FUNC(fd_readdir, "(i*~I*)i"),
  909. REG_NATIVE_FUNC(path_readlink, "(i*~*~*)i"),
  910. REG_NATIVE_FUNC(path_rename, "(i*~i*~)i"),
  911. REG_NATIVE_FUNC(fd_filestat_get, "(i*)i"),
  912. REG_NATIVE_FUNC(fd_filestat_set_times, "(iIIi)i"),
  913. REG_NATIVE_FUNC(fd_filestat_set_size, "(iI)i"),
  914. REG_NATIVE_FUNC(path_filestat_get, "(ii*~*)i"),
  915. REG_NATIVE_FUNC(path_filestat_set_times, "(ii*~IIi)i"),
  916. REG_NATIVE_FUNC(path_symlink, "(*~i*~)i"),
  917. REG_NATIVE_FUNC(path_unlink_file, "(i*~)i"),
  918. REG_NATIVE_FUNC(path_remove_directory, "(i*~)i"),
  919. REG_NATIVE_FUNC(poll_oneoff, "(**i*)i"),
  920. REG_NATIVE_FUNC(proc_exit, "(i)"),
  921. REG_NATIVE_FUNC(proc_raise, "(i)i"),
  922. REG_NATIVE_FUNC(random_get, "(*~)i"),
  923. REG_NATIVE_FUNC(sock_recv, "(i*ii**)i"),
  924. REG_NATIVE_FUNC(sock_send, "(i*ii*)i"),
  925. REG_NATIVE_FUNC(sock_shutdown, "(ii)i"),
  926. REG_NATIVE_FUNC(sched_yield, "()i"),
  927. };
  928. uint32
  929. get_libc_wasi_export_apis(NativeSymbol **p_libc_wasi_apis)
  930. {
  931. *p_libc_wasi_apis = native_symbols_libc_wasi;
  932. return sizeof(native_symbols_libc_wasi) / sizeof(NativeSymbol);
  933. }