wasm_runtime.c 41 KB

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