wasm_runtime.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "wasm_runtime.h"
  6. #include "wasm_loader.h"
  7. #include "wasm_interp.h"
  8. #include "bh_common.h"
  9. #include "bh_log.h"
  10. #include "mem_alloc.h"
  11. #include "../common/wasm_runtime_common.h"
  12. static void
  13. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  14. {
  15. if (error_buf != NULL)
  16. snprintf(error_buf, error_buf_size, "%s", string);
  17. }
  18. WASMModule*
  19. wasm_load(const uint8 *buf, uint32 size,
  20. char *error_buf, uint32 error_buf_size)
  21. {
  22. return wasm_loader_load(buf, size, error_buf, error_buf_size);
  23. }
  24. WASMModule*
  25. wasm_load_from_sections(WASMSection *section_list,
  26. char *error_buf, uint32_t error_buf_size)
  27. {
  28. return wasm_loader_load_from_sections(section_list,
  29. error_buf, error_buf_size);
  30. }
  31. void
  32. wasm_unload(WASMModule *module)
  33. {
  34. wasm_loader_unload(module);
  35. }
  36. /**
  37. * Destroy memory instances.
  38. */
  39. static void
  40. memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
  41. {
  42. uint32 i;
  43. if (memories) {
  44. for (i = 0; i < count; i++)
  45. if (memories[i]) {
  46. if (memories[i]->heap_handle)
  47. mem_allocator_destroy(memories[i]->heap_handle);
  48. wasm_runtime_free(memories[i]);
  49. }
  50. wasm_runtime_free(memories);
  51. }
  52. }
  53. static WASMMemoryInstance*
  54. memory_instantiate(uint32 num_bytes_per_page,
  55. uint32 init_page_count, uint32 max_page_count,
  56. uint32 global_data_size,
  57. uint32 heap_size,
  58. char *error_buf, uint32 error_buf_size)
  59. {
  60. WASMMemoryInstance *memory;
  61. uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
  62. (uint64)heap_size +
  63. num_bytes_per_page * (uint64)init_page_count +
  64. global_data_size;
  65. /* Allocate memory space, addr data and global data */
  66. if (total_size >= UINT32_MAX
  67. || !(memory = wasm_runtime_malloc((uint32)total_size))) {
  68. set_error_buf(error_buf, error_buf_size,
  69. "Instantiate memory failed: allocate memory failed.");
  70. return NULL;
  71. }
  72. memset(memory, 0, (uint32)total_size);
  73. memory->num_bytes_per_page = num_bytes_per_page;
  74. memory->cur_page_count = init_page_count;
  75. memory->max_page_count = max_page_count;
  76. memory->heap_data = memory->base_addr;
  77. memory->memory_data = memory->heap_data + heap_size;
  78. memory->global_data = memory->memory_data +
  79. num_bytes_per_page * memory->cur_page_count;
  80. memory->global_data_size = global_data_size;
  81. memory->end_addr = memory->global_data + global_data_size;
  82. bh_assert(memory->end_addr - (uint8*)memory == (uint32)total_size);
  83. /* Initialize heap */
  84. if (!(memory->heap_handle = mem_allocator_create
  85. (memory->heap_data, heap_size))) {
  86. wasm_runtime_free(memory);
  87. return NULL;
  88. }
  89. #if WASM_ENABLE_SPEC_TEST == 0
  90. memory->heap_base_offset = -(int32)heap_size;
  91. #else
  92. memory->heap_base_offset = 0;
  93. #endif
  94. return memory;
  95. }
  96. /**
  97. * Instantiate memories in a module.
  98. */
  99. static WASMMemoryInstance**
  100. memories_instantiate(const WASMModule *module,
  101. uint32 global_data_size, uint32 heap_size,
  102. char *error_buf, uint32 error_buf_size)
  103. {
  104. WASMImport *import;
  105. uint32 mem_index = 0, i, memory_count =
  106. module->import_memory_count + module->memory_count;
  107. uint64 total_size;
  108. WASMMemoryInstance **memories, *memory;
  109. if (memory_count == 0 && global_data_size > 0)
  110. memory_count = 1;
  111. total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count;
  112. if (total_size >= UINT32_MAX
  113. || !(memories = wasm_runtime_malloc((uint32)total_size))) {
  114. set_error_buf(error_buf, error_buf_size,
  115. "Instantiate memory failed: "
  116. "allocate memory failed.");
  117. return NULL;
  118. }
  119. memset(memories, 0, (uint32)total_size);
  120. /* instantiate memories from import section */
  121. import = module->import_memories;
  122. for (i = 0; i < module->import_memory_count; i++, import++) {
  123. if (!(memory = memories[mem_index++] =
  124. memory_instantiate(import->u.memory.num_bytes_per_page,
  125. import->u.memory.init_page_count,
  126. import->u.memory. max_page_count,
  127. global_data_size,
  128. heap_size, error_buf, error_buf_size))) {
  129. set_error_buf(error_buf, error_buf_size,
  130. "Instantiate memory failed: "
  131. "allocate memory failed.");
  132. memories_deinstantiate(memories, memory_count);
  133. return NULL;
  134. }
  135. }
  136. /* instantiate memories from memory section */
  137. for (i = 0; i < module->memory_count; i++) {
  138. if (!(memory = memories[mem_index++] =
  139. memory_instantiate(module->memories[i].num_bytes_per_page,
  140. module->memories[i].init_page_count,
  141. module->memories[i].max_page_count,
  142. global_data_size,
  143. heap_size, error_buf, error_buf_size))) {
  144. set_error_buf(error_buf, error_buf_size,
  145. "Instantiate memory failed: "
  146. "allocate memory failed.");
  147. memories_deinstantiate(memories, memory_count);
  148. return NULL;
  149. }
  150. }
  151. if (mem_index == 0) {
  152. /* no import memory and define memory, but has global variables */
  153. if (!(memory = memories[mem_index++] =
  154. memory_instantiate(0, 0, 0, global_data_size,
  155. heap_size, error_buf, error_buf_size))) {
  156. set_error_buf(error_buf, error_buf_size,
  157. "Instantiate memory failed: "
  158. "allocate memory failed.\n");
  159. memories_deinstantiate(memories, memory_count);
  160. return NULL;
  161. }
  162. }
  163. bh_assert(mem_index == memory_count);
  164. return memories;
  165. }
  166. /**
  167. * Destroy table instances.
  168. */
  169. static void
  170. tables_deinstantiate(WASMTableInstance **tables, uint32 count)
  171. {
  172. uint32 i;
  173. if (tables) {
  174. for (i = 0; i < count; i++)
  175. if (tables[i])
  176. wasm_runtime_free(tables[i]);
  177. wasm_runtime_free(tables);
  178. }
  179. }
  180. /**
  181. * Instantiate tables in a module.
  182. */
  183. static WASMTableInstance**
  184. tables_instantiate(const WASMModule *module,
  185. char *error_buf, uint32 error_buf_size)
  186. {
  187. WASMImport *import;
  188. uint32 table_index = 0, i, table_count =
  189. module->import_table_count + module->table_count;
  190. uint64 total_size = sizeof(WASMTableInstance*) * (uint64)table_count;
  191. WASMTableInstance **tables, *table;
  192. if (total_size >= UINT32_MAX
  193. || !(tables = wasm_runtime_malloc((uint32)total_size))) {
  194. set_error_buf(error_buf, error_buf_size,
  195. "Instantiate table failed: "
  196. "allocate memory failed.");
  197. return NULL;
  198. }
  199. memset(tables, 0, (uint32)total_size);
  200. /* instantiate tables from import section */
  201. import = module->import_tables;
  202. for (i = 0; i < module->import_table_count; i++, import++) {
  203. total_size = offsetof(WASMTableInstance, base_addr) +
  204. sizeof(uint32) * (uint64)import->u.table.init_size;
  205. if (total_size >= UINT32_MAX
  206. || !(table = tables[table_index++] =
  207. wasm_runtime_malloc((uint32)total_size))) {
  208. set_error_buf(error_buf, error_buf_size,
  209. "Instantiate table failed: "
  210. "allocate memory failed.");
  211. tables_deinstantiate(tables, table_count);
  212. return NULL;
  213. }
  214. /* Set all elements to -1 to mark them as uninitialized elements */
  215. memset(table, -1, (uint32)total_size);
  216. table->elem_type = import->u.table.elem_type;
  217. table->cur_size = import->u.table.init_size;
  218. table->max_size = import->u.table.max_size;
  219. }
  220. /* instantiate tables from table section */
  221. for (i = 0; i < module->table_count; i++) {
  222. total_size = offsetof(WASMTableInstance, base_addr) +
  223. sizeof(uint32) * (uint64)module->tables[i].init_size;
  224. if (total_size >= UINT32_MAX
  225. || !(table = tables[table_index++] =
  226. wasm_runtime_malloc((uint32)total_size))) {
  227. set_error_buf(error_buf, error_buf_size,
  228. "Instantiate table failed: "
  229. "allocate memory failed.");
  230. tables_deinstantiate(tables, table_count);
  231. return NULL;
  232. }
  233. /* Set all elements to -1 to mark them as uninitialized elements */
  234. memset(table, -1, (uint32)total_size);
  235. table->elem_type = module->tables[i].elem_type;
  236. table->cur_size = module->tables[i].init_size;
  237. table->max_size = module->tables[i].max_size;
  238. }
  239. bh_assert(table_index == table_count);
  240. return tables;
  241. }
  242. /**
  243. * Destroy function instances.
  244. */
  245. static void
  246. functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
  247. {
  248. if (functions) {
  249. wasm_runtime_free(functions);
  250. }
  251. }
  252. /**
  253. * Instantiate functions in a module.
  254. */
  255. static WASMFunctionInstance*
  256. functions_instantiate(const WASMModule *module,
  257. char *error_buf, uint32 error_buf_size)
  258. {
  259. WASMImport *import;
  260. uint32 i, function_count =
  261. module->import_function_count + module->function_count;
  262. uint64 total_size = sizeof(WASMFunctionInstance) * (uint64)function_count;
  263. WASMFunctionInstance *functions, *function;
  264. if (total_size >= UINT32_MAX
  265. || !(functions = wasm_runtime_malloc((uint32)total_size))) {
  266. set_error_buf(error_buf, error_buf_size,
  267. "Instantiate function failed: "
  268. "allocate memory failed.");
  269. return NULL;
  270. }
  271. memset(functions, 0, (uint32)total_size);
  272. /* instantiate functions from import section */
  273. function = functions;
  274. import = module->import_functions;
  275. for (i = 0; i < module->import_function_count; i++, import++) {
  276. function->is_import_func = true;
  277. function->u.func_import = &import->u.function;
  278. function->param_cell_num =
  279. wasm_type_param_cell_num(import->u.function.func_type);
  280. function->ret_cell_num =
  281. wasm_type_return_cell_num(import->u.function.func_type);
  282. function->local_cell_num = 0;
  283. function->param_count =
  284. (uint16)function->u.func_import->func_type->param_count;
  285. function->local_count = 0;
  286. function->param_types = function->u.func_import->func_type->types;
  287. function->local_types = NULL;
  288. function++;
  289. }
  290. /* instantiate functions from function section */
  291. for (i = 0; i < module->function_count; i++) {
  292. function->is_import_func = false;
  293. function->u.func = module->functions[i];
  294. function->param_cell_num = function->u.func->param_cell_num;
  295. function->ret_cell_num = function->u.func->ret_cell_num;
  296. function->local_cell_num = function->u.func->local_cell_num;
  297. function->param_count = (uint16)function->u.func->func_type->param_count;
  298. function->local_count = (uint16)function->u.func->local_count;
  299. function->param_types = function->u.func->func_type->types;
  300. function->local_types = function->u.func->local_types;
  301. function->local_offsets = function->u.func->local_offsets;
  302. #if WASM_ENABLE_FAST_INTERP != 0
  303. function->const_cell_num = function->u.func->const_cell_num;
  304. #endif
  305. function++;
  306. }
  307. bh_assert((uint32)(function - functions) == function_count);
  308. return functions;
  309. }
  310. /**
  311. * Destroy global instances.
  312. */
  313. static void
  314. globals_deinstantiate(WASMGlobalInstance *globals)
  315. {
  316. if (globals)
  317. wasm_runtime_free(globals);
  318. }
  319. /**
  320. * Instantiate globals in a module.
  321. */
  322. static WASMGlobalInstance*
  323. globals_instantiate(const WASMModule *module,
  324. uint32 *p_global_data_size,
  325. char *error_buf, uint32 error_buf_size)
  326. {
  327. WASMImport *import;
  328. uint32 global_data_offset = 0;
  329. uint32 i, global_count =
  330. module->import_global_count + module->global_count;
  331. uint64 total_size = sizeof(WASMGlobalInstance) * (uint64)global_count;
  332. WASMGlobalInstance *globals, *global;
  333. if (total_size >= UINT32_MAX
  334. || !(globals = wasm_runtime_malloc((uint32)total_size))) {
  335. set_error_buf(error_buf, error_buf_size,
  336. "Instantiate global failed: "
  337. "allocate memory failed.");
  338. return NULL;
  339. }
  340. memset(globals, 0, (uint32)total_size);
  341. /* instantiate globals from import section */
  342. global = globals;
  343. import = module->import_globals;
  344. for (i = 0; i < module->import_global_count; i++, import++) {
  345. WASMGlobalImport *global_import = &import->u.global;
  346. global->type = global_import->type;
  347. global->is_mutable = global_import->is_mutable;
  348. global->initial_value = global_import->global_data_linked;
  349. global->data_offset = global_data_offset;
  350. global_data_offset += wasm_value_type_size(global->type);
  351. global++;
  352. }
  353. /* instantiate globals from global section */
  354. for (i = 0; i < module->global_count; i++) {
  355. global->type = module->globals[i].type;
  356. global->is_mutable = module->globals[i].is_mutable;
  357. global->data_offset = global_data_offset;
  358. global_data_offset += wasm_value_type_size(global->type);
  359. global++;
  360. }
  361. bh_assert((uint32)(global - globals) == global_count);
  362. *p_global_data_size = global_data_offset;
  363. return globals;
  364. }
  365. static bool
  366. globals_instantiate_fix(WASMGlobalInstance *globals,
  367. const WASMModule *module,
  368. WASMModuleInstance *module_inst,
  369. char *error_buf, uint32 error_buf_size)
  370. {
  371. WASMGlobalInstance *global = globals;
  372. uint32 i;
  373. for (i = 0; i < module->global_count; i++) {
  374. InitializerExpression *init_expr = &module->globals[i].init_expr;
  375. if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  376. if (init_expr->u.global_index >= module->import_global_count + i) {
  377. set_error_buf(error_buf, error_buf_size,
  378. "Instantiate global failed: unknown global.");
  379. return false;
  380. }
  381. global->initial_value = globals[init_expr->u.global_index].initial_value;
  382. }
  383. else {
  384. bh_memcpy_s(&global->initial_value, sizeof(WASMValue),
  385. &init_expr->u, sizeof(init_expr->u));
  386. }
  387. global++;
  388. }
  389. return true;
  390. }
  391. /**
  392. * Return export function count in module export section.
  393. */
  394. static uint32
  395. get_export_function_count(const WASMModule *module)
  396. {
  397. WASMExport *export = module->exports;
  398. uint32 count = 0, i;
  399. for (i = 0; i < module->export_count; i++, export++)
  400. if (export->kind == EXPORT_KIND_FUNC)
  401. count++;
  402. return count;
  403. }
  404. /**
  405. * Destroy export function instances.
  406. */
  407. static void
  408. export_functions_deinstantiate(WASMExportFuncInstance *functions)
  409. {
  410. if (functions)
  411. wasm_runtime_free(functions);
  412. }
  413. /**
  414. * Instantiate export functions in a module.
  415. */
  416. static WASMExportFuncInstance*
  417. export_functions_instantiate(const WASMModule *module,
  418. WASMModuleInstance *module_inst,
  419. uint32 export_func_count,
  420. char *error_buf, uint32 error_buf_size)
  421. {
  422. WASMExportFuncInstance *export_funcs, *export_func;
  423. WASMExport *export = module->exports;
  424. uint32 i;
  425. uint64 total_size = sizeof(WASMExportFuncInstance) * (uint64)export_func_count;
  426. if (total_size >= UINT32_MAX
  427. || !(export_func = export_funcs = wasm_runtime_malloc((uint32)total_size))) {
  428. set_error_buf(error_buf, error_buf_size,
  429. "Instantiate export function failed: "
  430. "allocate memory failed.");
  431. return NULL;
  432. }
  433. memset(export_funcs, 0, (uint32)total_size);
  434. for (i = 0; i < module->export_count; i++, export++)
  435. if (export->kind == EXPORT_KIND_FUNC) {
  436. export_func->name = export->name;
  437. export_func->function = &module_inst->functions[export->index];
  438. export_func++;
  439. }
  440. bh_assert((uint32)(export_func - export_funcs) == export_func_count);
  441. return export_funcs;
  442. }
  443. static bool
  444. execute_post_inst_function(WASMModuleInstance *module_inst)
  445. {
  446. WASMFunctionInstance *post_inst_func = NULL;
  447. WASMType *post_inst_func_type;
  448. uint32 i;
  449. for (i = 0; i < module_inst->export_func_count; i++)
  450. if (!strcmp(module_inst->export_functions[i].name, "__post_instantiate")) {
  451. post_inst_func = module_inst->export_functions[i].function;
  452. break;
  453. }
  454. if (!post_inst_func)
  455. /* Not found */
  456. return true;
  457. post_inst_func_type = post_inst_func->u.func->func_type;
  458. if (post_inst_func_type->param_count != 0
  459. || post_inst_func_type->result_count != 0)
  460. /* Not a valid function type, ignore it */
  461. return true;
  462. return wasm_create_exec_env_and_call_function(module_inst, post_inst_func,
  463. 0, NULL);
  464. }
  465. static bool
  466. execute_start_function(WASMModuleInstance *module_inst)
  467. {
  468. WASMFunctionInstance *func = module_inst->start_function;
  469. if (!func)
  470. return true;
  471. bh_assert(!func->is_import_func && func->param_cell_num == 0
  472. && func->ret_cell_num == 0);
  473. return wasm_create_exec_env_and_call_function(module_inst, func, 0, NULL);
  474. }
  475. /**
  476. * Instantiate module
  477. */
  478. WASMModuleInstance*
  479. wasm_instantiate(WASMModule *module,
  480. uint32 stack_size, uint32 heap_size,
  481. char *error_buf, uint32 error_buf_size)
  482. {
  483. WASMModuleInstance *module_inst;
  484. WASMTableSeg *table_seg;
  485. WASMDataSeg *data_seg;
  486. WASMGlobalInstance *globals = NULL, *global;
  487. uint32 global_count, global_data_size = 0, i, j;
  488. uint32 base_offset, length, memory_size;
  489. uint8 *global_data, *global_data_end;
  490. uint8 *memory_data;
  491. uint32 *table_data;
  492. if (!module)
  493. return NULL;
  494. /* Check heap size */
  495. heap_size = align_uint(heap_size, 8);
  496. if (heap_size == 0)
  497. heap_size = APP_HEAP_SIZE_DEFAULT;
  498. if (heap_size < APP_HEAP_SIZE_MIN)
  499. heap_size = APP_HEAP_SIZE_MIN;
  500. if (heap_size > APP_HEAP_SIZE_MAX)
  501. heap_size = APP_HEAP_SIZE_MAX;
  502. /* Instantiate global firstly to get the mutable data size */
  503. global_count = module->import_global_count + module->global_count;
  504. if (global_count &&
  505. !(globals = globals_instantiate(module,
  506. &global_data_size,
  507. error_buf, error_buf_size)))
  508. return NULL;
  509. /* Allocate the memory */
  510. if (!(module_inst = wasm_runtime_malloc((uint32)sizeof(WASMModuleInstance)))) {
  511. set_error_buf(error_buf, error_buf_size,
  512. "Instantiate module failed: allocate memory failed.");
  513. globals_deinstantiate(globals);
  514. return NULL;
  515. }
  516. memset(module_inst, 0, (uint32)sizeof(WASMModuleInstance));
  517. module_inst->global_count = global_count;
  518. module_inst->globals = globals;
  519. module_inst->memory_count =
  520. module->import_memory_count + module->memory_count;
  521. module_inst->table_count =
  522. module->import_table_count + module->table_count;
  523. module_inst->function_count =
  524. module->import_function_count + module->function_count;
  525. module_inst->export_func_count = get_export_function_count(module);
  526. /* Instantiate memories/tables/functions */
  527. if (((module_inst->memory_count > 0 || global_count > 0)
  528. && !(module_inst->memories =
  529. memories_instantiate(module, global_data_size,
  530. heap_size, error_buf, error_buf_size)))
  531. || (module_inst->table_count > 0
  532. && !(module_inst->tables = tables_instantiate(module,
  533. error_buf,
  534. error_buf_size)))
  535. || (module_inst->function_count > 0
  536. && !(module_inst->functions = functions_instantiate(module,
  537. error_buf,
  538. error_buf_size)))
  539. || (module_inst->export_func_count > 0
  540. && !(module_inst->export_functions = export_functions_instantiate(
  541. module, module_inst, module_inst->export_func_count,
  542. error_buf, error_buf_size)))) {
  543. wasm_deinstantiate(module_inst);
  544. return NULL;
  545. }
  546. if (module_inst->memory_count || global_count > 0) {
  547. WASMMemoryInstance *memory;
  548. memory = module_inst->default_memory = module_inst->memories[0];
  549. memory_data = module_inst->default_memory->memory_data;
  550. /* fix import memoryBase */
  551. if (!globals_instantiate_fix(globals, module, module_inst,
  552. error_buf, error_buf_size)) {
  553. wasm_deinstantiate(module_inst);
  554. return NULL;
  555. }
  556. /* Initialize the global data */
  557. global_data = memory->global_data;
  558. global_data_end = global_data + global_data_size;
  559. global = globals;
  560. for (i = 0; i < global_count; i++, global++) {
  561. switch (global->type) {
  562. case VALUE_TYPE_I32:
  563. case VALUE_TYPE_F32:
  564. *(int32*)global_data = global->initial_value.i32;
  565. global_data += sizeof(int32);
  566. break;
  567. case VALUE_TYPE_I64:
  568. case VALUE_TYPE_F64:
  569. bh_memcpy_s(global_data, (uint32)(global_data_end - global_data),
  570. &global->initial_value.i64, sizeof(int64));
  571. global_data += sizeof(int64);
  572. break;
  573. default:
  574. bh_assert(0);
  575. }
  576. }
  577. bh_assert(global_data == global_data_end);
  578. /* Initialize the memory data with data segment section */
  579. if (module_inst->default_memory->cur_page_count > 0) {
  580. for (i = 0; i < module->data_seg_count; i++) {
  581. data_seg = module->data_segments[i];
  582. bh_assert(data_seg->memory_index == 0);
  583. bh_assert(data_seg->base_offset.init_expr_type ==
  584. INIT_EXPR_TYPE_I32_CONST
  585. || data_seg->base_offset.init_expr_type ==
  586. INIT_EXPR_TYPE_GET_GLOBAL);
  587. if (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  588. bh_assert(data_seg->base_offset.u.global_index < global_count
  589. && globals[data_seg->base_offset.u.global_index].type ==
  590. VALUE_TYPE_I32);
  591. data_seg->base_offset.u.i32 =
  592. globals[data_seg->base_offset.u.global_index].initial_value.i32;
  593. }
  594. base_offset = (uint32)data_seg->base_offset.u.i32;
  595. length = data_seg->data_length;
  596. memory_size = module_inst->default_memory->num_bytes_per_page
  597. * module_inst->default_memory->cur_page_count;
  598. if (length > 0
  599. && (base_offset >= memory_size
  600. || base_offset + length > memory_size)) {
  601. set_error_buf(error_buf, error_buf_size,
  602. "Instantiate module failed: data segment does not fit.");
  603. wasm_deinstantiate(module_inst);
  604. return NULL;
  605. }
  606. bh_memcpy_s(memory_data + base_offset, memory_size - base_offset,
  607. data_seg->data, length);
  608. }
  609. }
  610. }
  611. if (module_inst->table_count) {
  612. module_inst->default_table = module_inst->tables[0];
  613. /* Initialize the table data with table segment section */
  614. table_data = (uint32*)module_inst->default_table->base_addr;
  615. table_seg = module->table_segments;
  616. for (i = 0; i < module->table_seg_count; i++, table_seg++) {
  617. bh_assert(table_seg->table_index == 0);
  618. bh_assert(table_seg->base_offset.init_expr_type ==
  619. INIT_EXPR_TYPE_I32_CONST
  620. || table_seg->base_offset.init_expr_type ==
  621. INIT_EXPR_TYPE_GET_GLOBAL);
  622. if (table_seg->base_offset.init_expr_type ==
  623. INIT_EXPR_TYPE_GET_GLOBAL) {
  624. bh_assert(table_seg->base_offset.u.global_index < global_count
  625. && globals[table_seg->base_offset.u.global_index].type ==
  626. VALUE_TYPE_I32);
  627. table_seg->base_offset.u.i32 =
  628. globals[table_seg->base_offset.u.global_index].initial_value.i32;
  629. }
  630. if ((uint32)table_seg->base_offset.u.i32 <
  631. module_inst->default_table->cur_size) {
  632. length = table_seg->function_count;
  633. if ((uint32)table_seg->base_offset.u.i32 + length >
  634. module_inst->default_table->cur_size)
  635. length = module_inst->default_table->cur_size
  636. - (uint32)table_seg->base_offset.u.i32;
  637. /* Check function index */
  638. for (j = 0; j < length; j++) {
  639. if (table_seg->func_indexes[j] >= module_inst->function_count) {
  640. set_error_buf(error_buf, error_buf_size,
  641. "WASM instantiate failed: unknown function");
  642. wasm_deinstantiate(module_inst);
  643. return NULL;
  644. }
  645. }
  646. bh_memcpy_s(table_data + table_seg->base_offset.u.i32,
  647. (uint32)((module_inst->default_table->cur_size
  648. - (uint32)table_seg->base_offset.u.i32)
  649. * sizeof(uint32)),
  650. table_seg->func_indexes, (uint32)(length * sizeof(uint32)));
  651. }
  652. }
  653. }
  654. #if WASM_ENABLE_LIBC_WASI != 0
  655. if (!wasm_runtime_init_wasi((WASMModuleInstanceCommon*)module_inst,
  656. module->wasi_args.dir_list,
  657. module->wasi_args.dir_count,
  658. module->wasi_args.map_dir_list,
  659. module->wasi_args.map_dir_count,
  660. module->wasi_args.env,
  661. module->wasi_args.env_count,
  662. module->wasi_args.argv,
  663. module->wasi_args.argc,
  664. error_buf, error_buf_size)) {
  665. wasm_deinstantiate(module_inst);
  666. return NULL;
  667. }
  668. #endif
  669. if (module->start_function != (uint32)-1) {
  670. /* TODO: fix start function can be import function issue */
  671. if (module->start_function >= module->import_function_count)
  672. module_inst->start_function =
  673. &module_inst->functions[module->start_function];
  674. }
  675. module_inst->module = module;
  676. /* module instance type */
  677. module_inst->module_type = Wasm_Module_Bytecode;
  678. /* Initialize the thread related data */
  679. if (stack_size == 0)
  680. stack_size = DEFAULT_WASM_STACK_SIZE;
  681. #if WASM_ENABLE_SPEC_TEST != 0
  682. if (stack_size < 48 *1024)
  683. stack_size = 48 * 1024;
  684. #endif
  685. module_inst->default_wasm_stack_size = stack_size;
  686. /* Execute __post_instantiate function */
  687. if (!execute_post_inst_function(module_inst)
  688. || !execute_start_function(module_inst)) {
  689. set_error_buf(error_buf, error_buf_size,
  690. module_inst->cur_exception);
  691. wasm_deinstantiate(module_inst);
  692. return NULL;
  693. }
  694. (void)global_data_end;
  695. return module_inst;
  696. }
  697. void
  698. wasm_deinstantiate(WASMModuleInstance *module_inst)
  699. {
  700. if (!module_inst)
  701. return;
  702. #if WASM_ENABLE_LIBC_WASI != 0
  703. /* Destroy wasi resource before freeing app heap, since some fields of
  704. wasi contex are allocated from app heap, and if app heap is freed,
  705. these fields will be set to NULL, we cannot free their internal data
  706. which may allocated from global heap. */
  707. wasm_runtime_destroy_wasi((WASMModuleInstanceCommon*)module_inst);
  708. #endif
  709. if (module_inst->memory_count > 0)
  710. memories_deinstantiate(module_inst->memories, module_inst->memory_count);
  711. else if (module_inst->memories != NULL && module_inst->global_count > 0)
  712. /* No imported memory and defined memory, the memory is created when
  713. global count > 0. */
  714. memories_deinstantiate(module_inst->memories, 1);
  715. tables_deinstantiate(module_inst->tables, module_inst->table_count);
  716. functions_deinstantiate(module_inst->functions, module_inst->function_count);
  717. globals_deinstantiate(module_inst->globals);
  718. export_functions_deinstantiate(module_inst->export_functions);
  719. wasm_runtime_free(module_inst);
  720. }
  721. WASMFunctionInstance*
  722. wasm_lookup_function(const WASMModuleInstance *module_inst,
  723. const char *name, const char *signature)
  724. {
  725. uint32 i;
  726. for (i = 0; i < module_inst->export_func_count; i++)
  727. if (!strcmp(module_inst->export_functions[i].name, name))
  728. return module_inst->export_functions[i].function;
  729. (void)signature;
  730. return NULL;
  731. }
  732. bool
  733. wasm_call_function(WASMExecEnv *exec_env,
  734. WASMFunctionInstance *function,
  735. unsigned argc, uint32 argv[])
  736. {
  737. WASMModuleInstance *module_inst = (WASMModuleInstance*)exec_env->module_inst;
  738. wasm_interp_call_wasm(module_inst, exec_env, function, argc, argv);
  739. return !wasm_get_exception(module_inst) ? true : false;
  740. }
  741. bool
  742. wasm_create_exec_env_and_call_function(WASMModuleInstance *module_inst,
  743. WASMFunctionInstance *func,
  744. unsigned argc, uint32 argv[])
  745. {
  746. WASMExecEnv *exec_env;
  747. bool ret;
  748. if (!(exec_env = wasm_exec_env_create((WASMModuleInstanceCommon*)module_inst,
  749. module_inst->default_wasm_stack_size))) {
  750. wasm_set_exception(module_inst, "allocate memory failed.");
  751. return false;
  752. }
  753. /* set thread handle and stack boundary */
  754. wasm_exec_env_set_thread_info(exec_env);
  755. ret = wasm_call_function(exec_env, func, argc, argv);
  756. wasm_exec_env_destroy(exec_env);
  757. return ret;
  758. }
  759. void
  760. wasm_set_exception(WASMModuleInstance *module_inst,
  761. const char *exception)
  762. {
  763. if (exception)
  764. snprintf(module_inst->cur_exception,
  765. sizeof(module_inst->cur_exception),
  766. "Exception: %s", exception);
  767. else
  768. module_inst->cur_exception[0] = '\0';
  769. }
  770. const char*
  771. wasm_get_exception(WASMModuleInstance *module_inst)
  772. {
  773. if (module_inst->cur_exception[0] == '\0')
  774. return NULL;
  775. else
  776. return module_inst->cur_exception;
  777. }
  778. int32
  779. wasm_module_malloc(WASMModuleInstance *module_inst, uint32 size,
  780. void **p_native_addr)
  781. {
  782. WASMMemoryInstance *memory = module_inst->default_memory;
  783. uint8 *addr = mem_allocator_malloc(memory->heap_handle, size);
  784. if (!addr) {
  785. wasm_set_exception(module_inst, "out of memory");
  786. return 0;
  787. }
  788. if (p_native_addr)
  789. *p_native_addr = addr;
  790. return (int32)(addr - memory->memory_data);
  791. }
  792. void
  793. wasm_module_free(WASMModuleInstance *module_inst, int32 ptr)
  794. {
  795. if (ptr) {
  796. WASMMemoryInstance *memory = module_inst->default_memory;
  797. uint8 *addr = memory->memory_data + ptr;
  798. if (memory->heap_data < addr && addr < memory->memory_data)
  799. mem_allocator_free(memory->heap_handle, addr);
  800. }
  801. }
  802. int32
  803. wasm_module_dup_data(WASMModuleInstance *module_inst,
  804. const char *src, uint32 size)
  805. {
  806. char *buffer;
  807. int32 buffer_offset = wasm_module_malloc(module_inst, size,
  808. (void**)&buffer);
  809. if (buffer_offset != 0) {
  810. buffer = wasm_addr_app_to_native(module_inst, buffer_offset);
  811. bh_memcpy_s(buffer, size, src, size);
  812. }
  813. return buffer_offset;
  814. }
  815. bool
  816. wasm_validate_app_addr(WASMModuleInstance *module_inst,
  817. int32 app_offset, uint32 size)
  818. {
  819. WASMMemoryInstance *memory = module_inst->default_memory;
  820. int32 memory_data_size =
  821. (int32)(memory->num_bytes_per_page * memory->cur_page_count);
  822. /* integer overflow check */
  823. if (app_offset + (int32)size < app_offset) {
  824. goto fail;
  825. }
  826. if (app_offset <= memory->heap_base_offset
  827. || app_offset + (int32)size > memory_data_size) {
  828. goto fail;
  829. }
  830. return true;
  831. fail:
  832. wasm_set_exception(module_inst, "out of bounds memory access");
  833. return false;
  834. }
  835. bool
  836. wasm_validate_native_addr(WASMModuleInstance *module_inst,
  837. void *native_ptr, uint32 size)
  838. {
  839. uint8 *addr = (uint8*)native_ptr;
  840. WASMMemoryInstance *memory = module_inst->default_memory;
  841. int32 memory_data_size =
  842. (int32)(memory->num_bytes_per_page * memory->cur_page_count);
  843. if (addr + size < addr) {
  844. goto fail;
  845. }
  846. if (addr <= memory->heap_data
  847. || addr + size > memory->memory_data + memory_data_size) {
  848. goto fail;
  849. }
  850. return true;
  851. fail:
  852. wasm_set_exception(module_inst, "out of bounds memory access");
  853. return false;
  854. }
  855. void *
  856. wasm_addr_app_to_native(WASMModuleInstance *module_inst,
  857. int32 app_offset)
  858. {
  859. WASMMemoryInstance *memory = module_inst->default_memory;
  860. uint8 *addr = memory->memory_data + app_offset;
  861. int32 memory_data_size =
  862. (int32)(memory->num_bytes_per_page * memory->cur_page_count);
  863. if (memory->heap_data < addr
  864. && addr < memory->memory_data + memory_data_size)
  865. return addr;
  866. return NULL;
  867. }
  868. int32
  869. wasm_addr_native_to_app(WASMModuleInstance *module_inst,
  870. void *native_ptr)
  871. {
  872. WASMMemoryInstance *memory = module_inst->default_memory;
  873. uint8 *addr = (uint8*)native_ptr;
  874. int32 memory_data_size =
  875. (int32)(memory->num_bytes_per_page * memory->cur_page_count);
  876. if (memory->heap_data < addr
  877. && addr < memory->memory_data + memory_data_size)
  878. return (int32)(addr - memory->memory_data);
  879. return 0;
  880. }
  881. bool
  882. wasm_get_app_addr_range(WASMModuleInstance *module_inst,
  883. int32 app_offset,
  884. int32 *p_app_start_offset,
  885. int32 *p_app_end_offset)
  886. {
  887. WASMMemoryInstance *memory = module_inst->default_memory;
  888. int32 memory_data_size =
  889. (int32)(memory->num_bytes_per_page * memory->cur_page_count);
  890. if (memory->heap_base_offset < app_offset
  891. && app_offset < memory_data_size) {
  892. if (p_app_start_offset)
  893. *p_app_start_offset = memory->heap_base_offset;
  894. if (p_app_end_offset)
  895. *p_app_end_offset = memory_data_size;
  896. return true;
  897. }
  898. return false;
  899. }
  900. bool
  901. wasm_get_native_addr_range(WASMModuleInstance *module_inst,
  902. uint8 *native_ptr,
  903. uint8 **p_native_start_addr,
  904. uint8 **p_native_end_addr)
  905. {
  906. WASMMemoryInstance *memory = module_inst->default_memory;
  907. uint8 *addr = (uint8*)native_ptr;
  908. int32 memory_data_size =
  909. (int32)(memory->num_bytes_per_page * memory->cur_page_count);
  910. if (memory->heap_data < addr
  911. && addr < memory->memory_data + memory_data_size) {
  912. if (p_native_start_addr)
  913. *p_native_start_addr = memory->heap_data;
  914. if (p_native_end_addr)
  915. *p_native_end_addr = memory->memory_data + memory_data_size;
  916. return true;
  917. }
  918. return false;
  919. }
  920. bool
  921. wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
  922. {
  923. WASMMemoryInstance *memory = module->default_memory, *new_memory;
  924. uint32 heap_size = memory->memory_data - memory->heap_data;
  925. uint32 old_page_count = memory->cur_page_count;
  926. uint32 total_size_old = memory->end_addr - (uint8*)memory;
  927. uint32 total_page_count = inc_page_count + memory->cur_page_count;
  928. uint64 total_size = offsetof(WASMMemoryInstance, base_addr)
  929. + (uint64)heap_size
  930. + memory->num_bytes_per_page * (uint64)total_page_count
  931. + memory->global_data_size;
  932. uint8 *global_data_old;
  933. void *heap_handle_old = memory->heap_handle;
  934. if (inc_page_count <= 0)
  935. /* No need to enlarge memory */
  936. return true;
  937. if (total_page_count < memory->cur_page_count /* integer overflow */
  938. || total_page_count > memory->max_page_count) {
  939. wasm_set_exception(module, "fail to enlarge memory.");
  940. return false;
  941. }
  942. if (total_size >= UINT32_MAX) {
  943. wasm_set_exception(module, "fail to enlarge memory.");
  944. return false;
  945. }
  946. /* Destroy heap's lock firstly, if its memory is re-allocated,
  947. we cannot access its lock again. */
  948. mem_allocator_destroy_lock(memory->heap_handle);
  949. if (!(new_memory = wasm_runtime_realloc(memory, (uint32)total_size))) {
  950. if (!(new_memory = wasm_runtime_malloc((uint32)total_size))) {
  951. /* Restore heap's lock if memory re-alloc failed */
  952. mem_allocator_reinit_lock(memory->heap_handle);
  953. wasm_set_exception(module, "fail to enlarge memory.");
  954. return false;
  955. }
  956. bh_memcpy_s((uint8*)new_memory, (uint32)total_size,
  957. (uint8*)memory, total_size_old);
  958. wasm_runtime_free(memory);
  959. }
  960. memset((uint8*)new_memory + total_size_old,
  961. 0, (uint32)total_size - total_size_old);
  962. new_memory->heap_handle = (uint8*)heap_handle_old +
  963. ((uint8*)new_memory - (uint8*)memory);
  964. if (mem_allocator_migrate(new_memory->heap_handle,
  965. heap_handle_old) != 0) {
  966. wasm_set_exception(module, "fail to enlarge memory.");
  967. return false;
  968. }
  969. new_memory->cur_page_count = total_page_count;
  970. new_memory->heap_data = new_memory->base_addr;
  971. new_memory->memory_data = new_memory->base_addr + heap_size;
  972. new_memory->global_data = new_memory->memory_data +
  973. new_memory->num_bytes_per_page * total_page_count;
  974. new_memory->end_addr = new_memory->global_data + new_memory->global_data_size;
  975. global_data_old = new_memory->memory_data +
  976. new_memory->num_bytes_per_page * old_page_count;
  977. /* Copy global data */
  978. bh_memcpy_s(new_memory->global_data, new_memory->global_data_size,
  979. global_data_old, new_memory->global_data_size);
  980. memset(global_data_old, 0, new_memory->global_data_size);
  981. module->memories[0] = module->default_memory = new_memory;
  982. return true;
  983. }
  984. bool
  985. wasm_call_indirect(WASMExecEnv *exec_env,
  986. uint32_t element_indices,
  987. uint32_t argc, uint32_t argv[])
  988. {
  989. WASMModuleInstance *module_inst = NULL;
  990. WASMTableInstance *table_inst = NULL;
  991. uint32_t function_indices = 0;
  992. WASMFunctionInstance *function_inst = NULL;
  993. module_inst =
  994. (WASMModuleInstance*)exec_env->module_inst;
  995. bh_assert(module_inst);
  996. table_inst = module_inst->default_table;
  997. if (!table_inst) {
  998. wasm_set_exception(module_inst, "there is no table");
  999. goto got_exception;
  1000. }
  1001. if (element_indices >= table_inst->cur_size) {
  1002. wasm_set_exception(module_inst, "undefined element");
  1003. goto got_exception;
  1004. }
  1005. function_indices = ((uint32_t*)table_inst->base_addr)[element_indices];
  1006. if (function_indices == 0xFFFFFFFF) {
  1007. wasm_set_exception(module_inst, "uninitialized element");
  1008. goto got_exception;
  1009. }
  1010. function_inst = module_inst->functions + function_indices;
  1011. wasm_interp_call_wasm(module_inst, exec_env, function_inst, argc, argv);
  1012. return !wasm_get_exception(module_inst) ? true : false;
  1013. got_exception:
  1014. return false;
  1015. }