wasm-runtime.c 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "wasm-runtime.h"
  17. #include "wasm-thread.h"
  18. #include "wasm-loader.h"
  19. #include "wasm-native.h"
  20. #include "wasm-interp.h"
  21. #include "wasm_log.h"
  22. #include "wasm_platform_log.h"
  23. #include "wasm_memory.h"
  24. #include "mem_alloc.h"
  25. static void
  26. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  27. {
  28. if (error_buf != NULL)
  29. snprintf(error_buf, error_buf_size, "%s", string);
  30. }
  31. bool
  32. wasm_runtime_init()
  33. {
  34. if (wasm_platform_init() != 0)
  35. return false;
  36. if (wasm_log_init() != 0)
  37. return false;
  38. if (ws_thread_sys_init() != 0)
  39. return false;
  40. wasm_runtime_set_tlr(NULL);
  41. wasm_native_init();
  42. return true;
  43. }
  44. void
  45. wasm_runtime_destroy()
  46. {
  47. wasm_runtime_set_tlr(NULL);
  48. ws_thread_sys_destroy();
  49. }
  50. static void
  51. init_wasm_stack(WASMStack *wasm_stack, uint8 *stack, uint32 stack_size)
  52. {
  53. wasm_stack->top = wasm_stack->bottom = stack;
  54. wasm_stack->top_boundary = stack + stack_size;
  55. }
  56. bool
  57. wasm_runtime_call_wasm(WASMModuleInstance *module_inst,
  58. WASMExecEnv *exec_env,
  59. WASMFunctionInstance *function,
  60. unsigned argc, uint32 argv[])
  61. {
  62. if (!exec_env) {
  63. if (!module_inst->wasm_stack) {
  64. if (!(module_inst->wasm_stack =
  65. wasm_malloc(module_inst->wasm_stack_size))) {
  66. wasm_runtime_set_exception(module_inst, "allocate memory failed.");
  67. return false;
  68. }
  69. }
  70. init_wasm_stack(&module_inst->main_tlr.wasm_stack,
  71. module_inst->wasm_stack, module_inst->wasm_stack_size);
  72. }
  73. else {
  74. uintptr_t stack = (uintptr_t)exec_env->stack;
  75. uint32 stack_size;
  76. /* Set to 8 bytes align */
  77. stack = (stack + 7) & ~7;
  78. stack_size = exec_env->stack_size - (stack - (uintptr_t)exec_env->stack);
  79. if (!exec_env->stack || exec_env->stack_size <= 0
  80. || exec_env->stack_size < stack - (uintptr_t)exec_env->stack) {
  81. wasm_runtime_set_exception(module_inst, "Invalid execution stack info.");
  82. return false;
  83. }
  84. init_wasm_stack(&module_inst->main_tlr.wasm_stack, (uint8*)stack, stack_size);
  85. }
  86. wasm_interp_call_wasm(function, argc, argv);
  87. return !wasm_runtime_get_exception(module_inst) ? true : false;
  88. }
  89. void
  90. wasm_runtime_set_exception(WASMModuleInstance *module_inst,
  91. const char *exception)
  92. {
  93. if (exception)
  94. snprintf(module_inst->cur_exception,
  95. sizeof(module_inst->cur_exception),
  96. "Exception: %s", exception);
  97. else
  98. module_inst->cur_exception[0] = '\0';
  99. }
  100. const char*
  101. wasm_runtime_get_exception(WASMModuleInstance *module_inst)
  102. {
  103. if (module_inst->cur_exception[0] == '\0')
  104. return NULL;
  105. else
  106. return module_inst->cur_exception;
  107. }
  108. void
  109. wasm_runtime_clear_exception(WASMModuleInstance *module_inst)
  110. {
  111. wasm_runtime_set_exception(module_inst, NULL);
  112. }
  113. WASMModule*
  114. wasm_runtime_load(const uint8 *buf, uint32 size,
  115. char *error_buf, uint32 error_buf_size)
  116. {
  117. return wasm_loader_load(buf, size, error_buf, error_buf_size);
  118. }
  119. WASMModule*
  120. wasm_runtime_load_from_sections(WASMSection *section_list,
  121. char *error_buf, uint32_t error_buf_size)
  122. {
  123. return wasm_loader_load_from_sections(section_list,
  124. error_buf, error_buf_size);
  125. }
  126. void
  127. wasm_runtime_unload(WASMModule *module)
  128. {
  129. wasm_loader_unload(module);
  130. }
  131. /**
  132. * Destroy memory instances.
  133. */
  134. static void
  135. memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
  136. {
  137. uint32 i;
  138. if (memories) {
  139. for (i = 0; i < count; i++)
  140. if (memories[i]) {
  141. if (memories[i]->heap_handle)
  142. mem_allocator_destroy(memories[i]->heap_handle);
  143. wasm_free(memories[i]);
  144. }
  145. wasm_free(memories);
  146. }
  147. }
  148. static WASMMemoryInstance*
  149. memory_instantiate(uint32 init_page_count, uint32 max_page_count,
  150. uint32 addr_data_size, uint32 global_data_size,
  151. uint32 heap_size,
  152. char *error_buf, uint32 error_buf_size)
  153. {
  154. WASMMemoryInstance *memory;
  155. uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
  156. NumBytesPerPage * init_page_count +
  157. addr_data_size + global_data_size +
  158. heap_size;
  159. if (!(memory = wasm_malloc(total_size))) {
  160. set_error_buf(error_buf, error_buf_size,
  161. "Instantiate memory failed: allocate memory failed.");
  162. return NULL;
  163. }
  164. memset(memory, 0, total_size);
  165. memory->cur_page_count = init_page_count;
  166. memory->max_page_count = max_page_count;
  167. memory->addr_data = memory->base_addr;
  168. memory->addr_data_size = addr_data_size;
  169. memory->memory_data = memory->addr_data + addr_data_size;
  170. memory->heap_data = memory->memory_data +
  171. NumBytesPerPage * memory->cur_page_count;;
  172. memory->heap_data_size = heap_size;
  173. memory->global_data = memory->heap_data + memory->heap_data_size;
  174. memory->global_data_size = global_data_size;
  175. memory->end_addr = memory->global_data + global_data_size;
  176. /* Initialize heap */
  177. if (!(memory->heap_handle = mem_allocator_create
  178. (memory->heap_data, memory->heap_data_size))) {
  179. wasm_free(memory);
  180. return NULL;
  181. }
  182. return memory;
  183. }
  184. /**
  185. * Instantiate memories in a module.
  186. */
  187. static WASMMemoryInstance**
  188. memories_instantiate(const WASMModule *module, uint32 addr_data_size,
  189. uint32 global_data_size, uint32 heap_size,
  190. char *error_buf, uint32 error_buf_size)
  191. {
  192. WASMImport *import;
  193. uint32 mem_index = 0, i, memory_count =
  194. module->import_memory_count + module->memory_count;
  195. uint32 total_size;
  196. WASMMemoryInstance **memories, *memory;
  197. if (memory_count == 0 && global_data_size > 0)
  198. memory_count = 1;
  199. total_size = sizeof(WASMMemoryInstance*) * memory_count;
  200. memories = wasm_malloc(total_size);
  201. if (!memories) {
  202. set_error_buf(error_buf, error_buf_size,
  203. "Instantiate memory failed: "
  204. "allocate memory failed.");
  205. return NULL;
  206. }
  207. memset(memories, 0, total_size);
  208. /* instantiate memories from import section */
  209. import = module->import_memories;
  210. for (i = 0; i < module->import_memory_count; i++, import++) {
  211. if (!(memory = memories[mem_index++] =
  212. memory_instantiate(import->u.memory.init_page_count,
  213. import->u.memory. max_page_count,
  214. addr_data_size, global_data_size,
  215. heap_size, error_buf, error_buf_size))) {
  216. set_error_buf(error_buf, error_buf_size,
  217. "Instantiate memory failed: "
  218. "allocate memory failed.");
  219. memories_deinstantiate(memories, memory_count);
  220. return NULL;
  221. }
  222. }
  223. /* instantiate memories from memory section */
  224. for (i = 0; i < module->memory_count; i++) {
  225. if (!(memory = memories[mem_index++] =
  226. memory_instantiate(module->memories[i].init_page_count,
  227. module->memories[i].max_page_count,
  228. addr_data_size, global_data_size,
  229. heap_size, error_buf, error_buf_size))) {
  230. set_error_buf(error_buf, error_buf_size,
  231. "Instantiate memory failed: "
  232. "allocate memory failed.");
  233. memories_deinstantiate(memories, memory_count);
  234. return NULL;
  235. }
  236. }
  237. if (mem_index == 0) {
  238. /* no import memory and define memory, but has global variables */
  239. if (!(memory = memories[mem_index++] =
  240. memory_instantiate(0, 0, addr_data_size, global_data_size,
  241. heap_size, error_buf, error_buf_size))) {
  242. set_error_buf(error_buf, error_buf_size,
  243. "Instantiate memory failed: "
  244. "allocate memory failed.\n");
  245. memories_deinstantiate(memories, memory_count);
  246. return NULL;
  247. }
  248. }
  249. wasm_assert(mem_index == memory_count);
  250. return memories;
  251. }
  252. /**
  253. * Destroy table instances.
  254. */
  255. static void
  256. tables_deinstantiate(WASMTableInstance **tables, uint32 count)
  257. {
  258. uint32 i;
  259. if (tables) {
  260. for (i = 0; i < count; i++)
  261. if (tables[i])
  262. wasm_free(tables[i]);
  263. wasm_free(tables);
  264. }
  265. }
  266. /**
  267. * Instantiate tables in a module.
  268. */
  269. static WASMTableInstance**
  270. tables_instantiate(const WASMModule *module,
  271. char *error_buf, uint32 error_buf_size)
  272. {
  273. WASMImport *import;
  274. uint32 table_index = 0, i, table_count =
  275. module->import_table_count + module->table_count;
  276. uint32 total_size = sizeof(WASMTableInstance*) * table_count;
  277. WASMTableInstance **tables = wasm_malloc(total_size), *table;
  278. if (!tables) {
  279. set_error_buf(error_buf, error_buf_size,
  280. "Instantiate table failed: "
  281. "allocate memory failed.");
  282. return NULL;
  283. }
  284. memset(tables, 0, total_size);
  285. /* instantiate tables from import section */
  286. import = module->import_tables;
  287. for (i = 0; i < module->import_table_count; i++, import++) {
  288. total_size = offsetof(WASMTableInstance, base_addr) +
  289. sizeof(uint32) * import->u.table.init_size;
  290. if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
  291. set_error_buf(error_buf, error_buf_size,
  292. "Instantiate table failed: "
  293. "allocate memory failed.");
  294. tables_deinstantiate(tables, table_count);
  295. return NULL;
  296. }
  297. memset(table, 0, total_size);
  298. table->cur_size = import->u.table.init_size;
  299. table->max_size = import->u.table.max_size;
  300. }
  301. /* instantiate tables from table section */
  302. for (i = 0; i < module->table_count; i++) {
  303. total_size = offsetof(WASMTableInstance, base_addr) +
  304. sizeof(uint32) * module->tables[i].init_size;
  305. if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
  306. set_error_buf(error_buf, error_buf_size,
  307. "Instantiate table failed: "
  308. "allocate memory failed.");
  309. tables_deinstantiate(tables, table_count);
  310. return NULL;
  311. }
  312. memset(table, 0, total_size);
  313. table->cur_size = module->tables[i].init_size;
  314. table->max_size = module->tables[i].max_size;
  315. }
  316. wasm_assert(table_index == table_count);
  317. return tables;
  318. }
  319. /**
  320. * Destroy function instances.
  321. */
  322. static void
  323. functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
  324. {
  325. if (functions) {
  326. uint32 i;
  327. for (i = 0; i < count; i++)
  328. if (functions[i].local_offsets)
  329. wasm_free(functions[i].local_offsets);
  330. wasm_free(functions);
  331. }
  332. }
  333. static bool
  334. function_init_local_offsets(WASMFunctionInstance *func)
  335. {
  336. uint16 local_offset = 0;
  337. WASMType *param_type = func->u.func->func_type;
  338. uint32 param_count = param_type->param_count;
  339. uint8 *param_types = param_type->types;
  340. uint32 local_count = func->u.func->local_count;
  341. uint8 *local_types = func->u.func->local_types;
  342. uint32 i, total_size = (param_count + local_count) * sizeof(uint16);
  343. if (!(func->local_offsets = wasm_malloc(total_size)))
  344. return false;
  345. for (i = 0; i < param_count; i++) {
  346. func->local_offsets[i] = local_offset;
  347. local_offset += wasm_value_type_cell_num(param_types[i]);
  348. }
  349. for (i = 0; i < local_count; i++) {
  350. func->local_offsets[param_count + i] = local_offset;
  351. local_offset += wasm_value_type_cell_num(local_types[i]);
  352. }
  353. wasm_assert(local_offset == func->param_cell_num + func->local_cell_num);
  354. return true;
  355. }
  356. /**
  357. * Instantiate functions in a module.
  358. */
  359. static WASMFunctionInstance*
  360. functions_instantiate(const WASMModule *module,
  361. char *error_buf, uint32 error_buf_size)
  362. {
  363. WASMImport *import;
  364. uint32 i, function_count =
  365. module->import_function_count + module->function_count;
  366. uint32 total_size = sizeof(WASMFunctionInstance) * function_count;
  367. WASMFunctionInstance *functions = wasm_malloc(total_size), *function;
  368. if (!functions) {
  369. set_error_buf(error_buf, error_buf_size,
  370. "Instantiate function failed: "
  371. "allocate memory failed.");
  372. return NULL;
  373. }
  374. memset(functions, 0, total_size);
  375. /* instantiate functions from import section */
  376. function = functions;
  377. import = module->import_functions;
  378. for (i = 0; i < module->import_function_count; i++, import++) {
  379. function->is_import_func = true;
  380. function->u.func_import = &import->u.function;
  381. function->param_cell_num =
  382. wasm_type_param_cell_num(import->u.function.func_type);
  383. function->ret_cell_num =
  384. wasm_type_return_cell_num(import->u.function.func_type);
  385. function->local_cell_num = 0;
  386. function++;
  387. }
  388. /* instantiate functions from function section */
  389. for (i = 0; i < module->function_count; i++) {
  390. function->is_import_func = false;
  391. function->u.func = module->functions[i];
  392. function->param_cell_num =
  393. wasm_type_param_cell_num(function->u.func->func_type);
  394. function->ret_cell_num =
  395. wasm_type_return_cell_num(function->u.func->func_type);
  396. function->local_cell_num =
  397. wasm_get_cell_num(function->u.func->local_types,
  398. function->u.func->local_count);
  399. if (!function_init_local_offsets(function)) {
  400. functions_deinstantiate(functions, function_count);
  401. return NULL;
  402. }
  403. function++;
  404. }
  405. wasm_assert((uint32)(function - functions) == function_count);
  406. return functions;
  407. }
  408. /**
  409. * Destroy global instances.
  410. */
  411. static void
  412. globals_deinstantiate(WASMGlobalInstance *globals)
  413. {
  414. if (globals)
  415. wasm_free(globals);
  416. }
  417. /**
  418. * Instantiate globals in a module.
  419. */
  420. static WASMGlobalInstance*
  421. globals_instantiate(const WASMModule *module,
  422. uint32 *p_addr_data_size,
  423. uint32 *p_global_data_size,
  424. char *error_buf, uint32 error_buf_size)
  425. {
  426. WASMImport *import;
  427. uint32 addr_data_offset = 0, global_data_offset = 0;
  428. uint32 i, global_count =
  429. module->import_global_count + module->global_count;
  430. uint32 total_size = sizeof(WASMGlobalInstance) * global_count;
  431. WASMGlobalInstance *globals = wasm_malloc(total_size), *global;
  432. if (!globals) {
  433. set_error_buf(error_buf, error_buf_size,
  434. "Instantiate global failed: "
  435. "allocate memory failed.");
  436. return NULL;
  437. }
  438. memset(globals, 0, total_size);
  439. /* instantiate globals from import section */
  440. global = globals;
  441. import = module->import_globals;
  442. for (i = 0; i < module->import_global_count; i++, import++) {
  443. WASMGlobalImport *global_import = &import->u.global;
  444. global->type = global_import->type;
  445. global->is_mutable = global_import->is_mutable;
  446. global->is_addr = global_import->is_addr;
  447. global->initial_value = global_import->global_data_linked;
  448. global->data_offset = global_data_offset;
  449. global_data_offset += wasm_value_type_size(global->type);
  450. if (global->is_addr)
  451. addr_data_offset += sizeof(uint32);
  452. global++;
  453. }
  454. /* instantiate globals from global section */
  455. for (i = 0; i < module->global_count; i++) {
  456. global->type = module->globals[i].type;
  457. global->is_mutable = module->globals[i].is_mutable;
  458. global->is_addr = module->globals[i].is_addr;
  459. global->data_offset = global_data_offset;
  460. global_data_offset += wasm_value_type_size(global->type);
  461. if (global->is_addr)
  462. addr_data_offset += sizeof(uint32);
  463. global++;
  464. }
  465. wasm_assert((uint32)(global - globals) == global_count);
  466. *p_addr_data_size = addr_data_offset;
  467. *p_global_data_size = global_data_offset;
  468. return globals;
  469. }
  470. static void
  471. globals_instantiate_fix(WASMGlobalInstance *globals,
  472. const WASMModule *module,
  473. WASMModuleInstance *module_inst)
  474. {
  475. WASMGlobalInstance *global = globals;
  476. WASMImport *import = module->import_globals;
  477. uint32 i;
  478. /* Fix globals from import section */
  479. for (i = 0; i < module->import_global_count; i++, import++, global++) {
  480. if (!strcmp(import->u.names.module_name, "env")) {
  481. if (!strcmp(import->u.names.field_name, "memoryBase")
  482. || !strcmp(import->u.names.field_name, "__memory_base")) {
  483. global->initial_value.addr = 0;
  484. }
  485. else if (!strcmp(import->u.names.field_name, "tableBase")
  486. || !strcmp(import->u.names.field_name, "__table_base")) {
  487. global->initial_value.addr = 0;
  488. }
  489. else if (!strcmp(import->u.names.field_name, "DYNAMICTOP_PTR")) {
  490. global->initial_value.i32 =
  491. NumBytesPerPage * module_inst->default_memory->cur_page_count;
  492. module_inst->DYNAMICTOP_PTR_offset = global->data_offset;
  493. }
  494. else if (!strcmp(import->u.names.field_name, "STACKTOP")) {
  495. global->initial_value.i32 = 0;
  496. }
  497. else if (!strcmp(import->u.names.field_name, "STACK_MAX")) {
  498. /* Unused in emcc wasm bin actually. */
  499. global->initial_value.i32 = 0;
  500. }
  501. }
  502. }
  503. for (i = 0; i < module->global_count; i++) {
  504. InitializerExpression *init_expr = &module->globals[i].init_expr;
  505. if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  506. wasm_assert(init_expr->u.global_index < module->import_global_count);
  507. global->initial_value = globals[init_expr->u.global_index].initial_value;
  508. }
  509. else {
  510. memcpy(&global->initial_value, &init_expr->u, sizeof(int64));
  511. }
  512. global++;
  513. }
  514. }
  515. /**
  516. * Return export function count in module export section.
  517. */
  518. static uint32
  519. get_export_function_count(const WASMModule *module)
  520. {
  521. WASMExport *export = module->exports;
  522. uint32 count = 0, i;
  523. for (i = 0; i < module->export_count; i++, export++)
  524. if (export->kind == EXPORT_KIND_FUNC)
  525. count++;
  526. return count;
  527. }
  528. /**
  529. * Destroy export function instances.
  530. */
  531. static void
  532. export_functions_deinstantiate(WASMExportFuncInstance *functions)
  533. {
  534. if (functions)
  535. wasm_free(functions);
  536. }
  537. /**
  538. * Instantiate export functions in a module.
  539. */
  540. static WASMExportFuncInstance*
  541. export_functions_instantiate(const WASMModule *module,
  542. WASMModuleInstance *module_inst,
  543. uint32 export_func_count,
  544. char *error_buf, uint32 error_buf_size)
  545. {
  546. WASMExportFuncInstance *export_funcs, *export_func;
  547. WASMExport *export = module->exports;
  548. uint32 i, total_size = sizeof(WASMExportFuncInstance) * export_func_count;
  549. if (!(export_func = export_funcs = wasm_malloc(total_size))) {
  550. set_error_buf(error_buf, error_buf_size,
  551. "Instantiate export function failed: "
  552. "allocate memory failed.");
  553. return NULL;
  554. }
  555. memset(export_funcs, 0, total_size);
  556. for (i = 0; i < module->export_count; i++, export++)
  557. if (export->kind == EXPORT_KIND_FUNC) {
  558. wasm_assert(export->index >= module->import_function_count
  559. && export->index < module->import_function_count
  560. + module->function_count);
  561. export_func->name = export->name;
  562. export_func->function = &module_inst->functions[export->index];
  563. export_func++;
  564. }
  565. wasm_assert((uint32)(export_func - export_funcs) == export_func_count);
  566. return export_funcs;
  567. }
  568. void
  569. wasm_runtime_deinstantiate(WASMModuleInstance *module_inst);
  570. static bool
  571. execute_post_inst_function(WASMModuleInstance *module_inst)
  572. {
  573. WASMFunctionInstance *post_inst_func = NULL;
  574. WASMType *post_inst_func_type;
  575. uint32 i;
  576. for (i = 0; i < module_inst->export_func_count; i++)
  577. if (!strcmp(module_inst->export_functions[i].name, "__post_instantiate")) {
  578. post_inst_func = module_inst->export_functions[i].function;
  579. break;
  580. }
  581. if (!post_inst_func)
  582. /* Not found */
  583. return true;
  584. post_inst_func_type = post_inst_func->u.func->func_type;
  585. if (post_inst_func_type->param_count != 0
  586. || post_inst_func_type->result_count != 0)
  587. /* Not a valid function type, ignore it */
  588. return true;
  589. return wasm_runtime_call_wasm(module_inst, NULL, post_inst_func, 0, NULL);
  590. }
  591. static bool
  592. execute_start_function(WASMModuleInstance *module_inst)
  593. {
  594. WASMFunctionInstance *func = module_inst->start_function;
  595. if (!func)
  596. return true;
  597. wasm_assert(!func->is_import_func && func->param_cell_num == 0
  598. && func->ret_cell_num == 0);
  599. return wasm_runtime_call_wasm(module_inst, NULL, func, 0, NULL);
  600. }
  601. /**
  602. * Instantiate module
  603. */
  604. WASMModuleInstance*
  605. wasm_runtime_instantiate(const WASMModule *module,
  606. uint32 stack_size, uint32 heap_size,
  607. char *error_buf, uint32 error_buf_size)
  608. {
  609. WASMModuleInstance *module_inst;
  610. WASMTableSeg *table_seg;
  611. WASMDataSeg *data_seg;
  612. WASMGlobalInstance *globals = NULL, *global;
  613. uint32 global_count, addr_data_size = 0, global_data_size = 0, i;
  614. uint32 base_offset, length, memory_size;
  615. uint8 *global_data, *global_data_end, *addr_data, *addr_data_end;
  616. uint8 *memory_data;
  617. uint32 *table_data;
  618. if (!module)
  619. return NULL;
  620. /* Check heap size */
  621. heap_size = align_uint(heap_size, 8);
  622. if (heap_size == 0)
  623. heap_size = DEFAULT_WASM_HEAP_SIZE;
  624. if (heap_size < MIN_WASM_HEAP_SIZE)
  625. heap_size = MIN_WASM_HEAP_SIZE;
  626. /* Instantiate global firstly to get the mutable data size */
  627. global_count = module->import_global_count + module->global_count;
  628. if (global_count &&
  629. !(globals = globals_instantiate(module, &addr_data_size,
  630. &global_data_size,
  631. error_buf, error_buf_size)))
  632. return NULL;
  633. /* Allocate the memory */
  634. if (!(module_inst = wasm_malloc(sizeof(WASMModuleInstance)))) {
  635. set_error_buf(error_buf, error_buf_size,
  636. "Instantiate module failed: allocate memory failed.");
  637. globals_deinstantiate(globals);
  638. return NULL;
  639. }
  640. memset(module_inst, 0, sizeof(WASMModuleInstance));
  641. module_inst->global_count = global_count;
  642. module_inst->globals = globals;
  643. module_inst->memory_count =
  644. module->import_memory_count + module->memory_count;
  645. module_inst->table_count =
  646. module->import_table_count + module->table_count;
  647. module_inst->function_count =
  648. module->import_function_count + module->function_count;
  649. module_inst->export_func_count = get_export_function_count(module);
  650. /* Instantiate memories/tables/functions */
  651. if (((module_inst->memory_count > 0 || global_count > 0)
  652. && !(module_inst->memories =
  653. memories_instantiate(module, addr_data_size, global_data_size,
  654. heap_size, error_buf, error_buf_size)))
  655. || (module_inst->table_count > 0
  656. && !(module_inst->tables = tables_instantiate(module,
  657. error_buf,
  658. error_buf_size)))
  659. || (module_inst->function_count > 0
  660. && !(module_inst->functions = functions_instantiate(module,
  661. error_buf,
  662. error_buf_size)))
  663. || (module_inst->export_func_count > 0
  664. && !(module_inst->export_functions = export_functions_instantiate(
  665. module, module_inst, module_inst->export_func_count,
  666. error_buf, error_buf_size)))) {
  667. wasm_runtime_deinstantiate(module_inst);
  668. return NULL;
  669. }
  670. if (module_inst->memory_count || global_count > 0) {
  671. WASMMemoryInstance *memory;
  672. memory = module_inst->default_memory = module_inst->memories[0];
  673. memory_data = module_inst->default_memory->memory_data;
  674. /* fix import memoryBase */
  675. globals_instantiate_fix(globals, module, module_inst);
  676. /* Initialize the global data */
  677. addr_data = memory->addr_data;
  678. addr_data_end = addr_data + addr_data_size;
  679. global_data = memory->global_data;
  680. global_data_end = global_data + global_data_size;
  681. global = globals;
  682. for (i = 0; i < global_count; i++, global++) {
  683. switch (global->type) {
  684. case VALUE_TYPE_I32:
  685. case VALUE_TYPE_F32:
  686. if (!global->is_addr)
  687. *(int32*)global_data = global->initial_value.i32;
  688. else {
  689. *(int32*)addr_data = global->initial_value.i32;
  690. /* Store the offset to memory data for global of addr */
  691. *(int32*)global_data = addr_data - memory_data;
  692. addr_data += sizeof(int32);
  693. }
  694. global_data += sizeof(int32);
  695. break;
  696. case VALUE_TYPE_I64:
  697. case VALUE_TYPE_F64:
  698. wasm_assert(!global->is_addr);
  699. memcpy(global_data, &global->initial_value.i64, sizeof(int64));
  700. global_data += sizeof(int64);
  701. break;
  702. default:
  703. wasm_assert(0);
  704. }
  705. }
  706. wasm_assert(addr_data == addr_data_end);
  707. wasm_assert(global_data == global_data_end);
  708. global = globals + module->import_global_count;
  709. for (i = 0; i < module->global_count; i++, global++) {
  710. InitializerExpression *init_expr = &module->globals[i].init_expr;
  711. if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
  712. && globals[init_expr->u.global_index].is_addr) {
  713. uint8 *global_data_dst = memory->global_data + global->data_offset;
  714. uint8 *global_data_src =
  715. memory->global_data + globals[init_expr->u.global_index].data_offset;
  716. *(uintptr_t*)global_data_dst = *(uintptr_t*)global_data_src;
  717. }
  718. }
  719. /* Initialize the memory data with data segment section */
  720. if (module_inst->default_memory->cur_page_count > 0) {
  721. for (i = 0; i < module->data_seg_count; i++) {
  722. data_seg = module->data_segments[i];
  723. wasm_assert(data_seg->memory_index == 0);
  724. wasm_assert(data_seg->base_offset.init_expr_type ==
  725. INIT_EXPR_TYPE_I32_CONST
  726. || data_seg->base_offset.init_expr_type ==
  727. INIT_EXPR_TYPE_GET_GLOBAL);
  728. if (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  729. wasm_assert(data_seg->base_offset.u.global_index < global_count
  730. && globals[data_seg->base_offset.u.global_index].type ==
  731. VALUE_TYPE_I32);
  732. data_seg->base_offset.u.i32 =
  733. globals[data_seg->base_offset.u.global_index].initial_value.i32;
  734. }
  735. base_offset = (uint32)data_seg->base_offset.u.i32;
  736. length = data_seg->data_length;
  737. memory_size = NumBytesPerPage * module_inst->default_memory->cur_page_count;
  738. if (base_offset >= memory_size
  739. || base_offset + length > memory_size) {
  740. set_error_buf(error_buf, error_buf_size,
  741. "Instantiate module failed: data segment out of range.");
  742. wasm_runtime_deinstantiate(module_inst);
  743. return NULL;
  744. }
  745. memcpy(memory_data + base_offset, data_seg->data, length);
  746. }
  747. }
  748. }
  749. if (module_inst->table_count) {
  750. module_inst->default_table = module_inst->tables[0];
  751. /* Initialize the table data with table segment section */
  752. table_data = (uint32*)module_inst->default_table->base_addr;
  753. table_seg = module->table_segments;
  754. for (i = 0; i < module->table_seg_count; i++, table_seg++) {
  755. wasm_assert(table_seg->table_index == 0);
  756. wasm_assert(table_seg->base_offset.init_expr_type ==
  757. INIT_EXPR_TYPE_I32_CONST
  758. || table_seg->base_offset.init_expr_type ==
  759. INIT_EXPR_TYPE_GET_GLOBAL);
  760. if (table_seg->base_offset.init_expr_type ==
  761. INIT_EXPR_TYPE_GET_GLOBAL) {
  762. wasm_assert(table_seg->base_offset.u.global_index < global_count
  763. && globals[table_seg->base_offset.u.global_index].type ==
  764. VALUE_TYPE_I32);
  765. table_seg->base_offset.u.i32 =
  766. globals[table_seg->base_offset.u.global_index].initial_value.i32;
  767. }
  768. if ((uint32)table_seg->base_offset.u.i32 <
  769. module_inst->default_table->cur_size) {
  770. length = table_seg->function_count;
  771. if (table_seg->base_offset.u.i32 + length >
  772. module_inst->default_table->cur_size)
  773. length = module_inst->default_table->cur_size
  774. - table_seg->base_offset.u.i32;
  775. memcpy(table_data + table_seg->base_offset.u.i32,
  776. table_seg->func_indexes, length * sizeof(uint32));
  777. }
  778. }
  779. }
  780. if (module->start_function != (uint32)-1) {
  781. wasm_assert(module->start_function >= module->import_function_count);
  782. module_inst->start_function =
  783. &module_inst->functions[module->start_function];
  784. }
  785. module_inst->branch_set = module->branch_set;
  786. module_inst->module = module;
  787. /* module instance type */
  788. module_inst->module_type = Wasm_Module_Bytecode;
  789. /* Initialize the thread related data */
  790. if (stack_size == 0)
  791. stack_size = DEFAULT_WASM_STACK_SIZE;
  792. module_inst->wasm_stack_size = stack_size;
  793. module_inst->main_tlr.module_inst = module_inst;
  794. /* Bind thread data with current native thread:
  795. set thread local root to current thread. */
  796. wasm_runtime_set_tlr(&module_inst->main_tlr);
  797. module_inst->main_tlr.handle = ws_self_thread();
  798. /* Execute __post_instantiate function */
  799. if (!execute_post_inst_function(module_inst)) {
  800. const char *exception = wasm_runtime_get_exception(module_inst);
  801. wasm_printf("%s\n", exception);
  802. wasm_runtime_deinstantiate(module_inst);
  803. return NULL;
  804. }
  805. /* Execute start function */
  806. if (!execute_start_function(module_inst)) {
  807. const char *exception = wasm_runtime_get_exception(module_inst);
  808. wasm_printf("%s\n", exception);
  809. wasm_runtime_deinstantiate(module_inst);
  810. return NULL;
  811. }
  812. (void)addr_data_end;
  813. (void)global_data_end;
  814. return module_inst;
  815. }
  816. void
  817. wasm_runtime_deinstantiate(WASMModuleInstance *module_inst)
  818. {
  819. if (!module_inst)
  820. return;
  821. if (module_inst->memory_count > 0)
  822. memories_deinstantiate(module_inst->memories, module_inst->memory_count);
  823. else if (module_inst->memories != NULL && module_inst->global_count > 0)
  824. /* No imported memory and defined memory, the memory is created when
  825. global count > 0. */
  826. memories_deinstantiate(module_inst->memories, 1);
  827. tables_deinstantiate(module_inst->tables, module_inst->table_count);
  828. functions_deinstantiate(module_inst->functions, module_inst->function_count);
  829. globals_deinstantiate(module_inst->globals);
  830. export_functions_deinstantiate(module_inst->export_functions);
  831. if (module_inst->wasm_stack)
  832. wasm_free(module_inst->wasm_stack);
  833. wasm_free(module_inst);
  834. }
  835. bool
  836. wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
  837. {
  838. #if 1
  839. wasm_runtime_set_exception(module, "unsupported operation: enlarge memory.");
  840. return false;
  841. #else
  842. WASMMemoryInstance *memory = module->default_memory;
  843. WASMMemoryInstance *new_memory;
  844. uint32 total_page_count = inc_page_count + memory->cur_page_count;
  845. uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
  846. memory->addr_data_size +
  847. NumBytesPerPage * total_page_count +
  848. memory->global_data_size +
  849. memory->thunk_argv_data_size +
  850. sizeof(uint32) * memory->thunk_argc;
  851. if (!(new_memory = wasm_malloc(total_size))) {
  852. wasm_runtime_set_exception(module, "alloc memory for enlarge memory failed.");
  853. return false;
  854. }
  855. new_memory->cur_page_count = total_page_count;
  856. new_memory->max_page_count = memory->max_page_count > total_page_count
  857. ? memory->max_page_count : total_page_count;
  858. new_memory->addr_data = new_memory->base_addr;
  859. new_memory->addr_data_size = memory->addr_data_size;
  860. new_memory->thunk_argv_data = new_memory->addr_data + memory->addr_data_size;
  861. new_memory->thunk_argv_data_size = memory->thunk_argv_data_size;
  862. new_memory->thunk_argc = memory->thunk_argc;
  863. new_memory->thunk_argv_offsets = new_memory->thunk_argv_data +
  864. memory->thunk_argv_data_size;
  865. new_memory->memory_data = new_memory->thunk_argv_offsets +
  866. sizeof(uint32) * memory->thunk_argc;
  867. new_memory->global_data = new_memory->memory_data +
  868. NumBytesPerPage * new_memory->cur_page_count;
  869. new_memory->global_data_size = memory->global_data_size;
  870. new_memory->end_addr = new_memory->global_data + memory->global_data_size;
  871. /* Copy addr data, thunk argv data, thunk argv offsets and memory data */
  872. memcpy(new_memory->addr_data, memory->addr_data,
  873. memory->global_data - memory->addr_data);
  874. /* Copy global data */
  875. memcpy(new_memory->global_data, memory->global_data,
  876. memory->end_addr - memory->global_data);
  877. /* Init free space of new memory */
  878. memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count,
  879. 0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
  880. wasm_free(memory);
  881. module->memories[0] = module->default_memory = new_memory;
  882. return true;
  883. #endif
  884. }
  885. PackageType
  886. get_package_type(const uint8 *buf, uint32 size)
  887. {
  888. if (buf && size > 4) {
  889. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 's' && buf[3] == 'm')
  890. return Wasm_Module_Bytecode;
  891. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 'o' && buf[3] == 't')
  892. return Wasm_Module_AoT;
  893. }
  894. return Package_Type_Unknown;
  895. }
  896. WASMExecEnv*
  897. wasm_runtime_create_exec_env(uint32 stack_size)
  898. {
  899. WASMExecEnv *exec_env = wasm_malloc(sizeof(WASMExecEnv));
  900. if (exec_env) {
  901. if (!(exec_env->stack = wasm_malloc(stack_size))) {
  902. wasm_free(exec_env);
  903. return NULL;
  904. }
  905. exec_env->stack_size = stack_size;
  906. }
  907. return exec_env;
  908. }
  909. void
  910. wasm_runtime_destory_exec_env(WASMExecEnv *env)
  911. {
  912. if (env) {
  913. wasm_free(env->stack);
  914. wasm_free(env);
  915. }
  916. }
  917. bool
  918. wasm_runtime_attach_current_thread(WASMModuleInstance *module_inst,
  919. void *thread_data)
  920. {
  921. wasm_runtime_set_tlr(&module_inst->main_tlr);
  922. module_inst->main_tlr.handle = ws_self_thread();
  923. module_inst->thread_data = thread_data;
  924. return true;
  925. }
  926. void
  927. wasm_runtime_detach_current_thread(WASMModuleInstance *module_inst)
  928. {
  929. module_inst->thread_data = NULL;
  930. }
  931. void*
  932. wasm_runtime_get_current_thread_data()
  933. {
  934. WASMThread *tlr = wasm_runtime_get_self();
  935. return (tlr && tlr->module_inst) ? tlr->module_inst->thread_data : NULL;
  936. }
  937. WASMModuleInstance *
  938. wasm_runtime_get_current_module_inst()
  939. {
  940. WASMThread *tlr = wasm_runtime_get_self();
  941. return tlr ? tlr->module_inst : NULL;
  942. }
  943. int32
  944. wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size)
  945. {
  946. uint8 *memory_base = module_inst->default_memory->memory_data;
  947. void *heap = module_inst->default_memory->heap_handle;
  948. uint8 *addr = mem_allocator_malloc(heap, size);
  949. if (!addr)
  950. wasm_runtime_set_exception(module_inst, "out of memory");
  951. return addr ? addr - memory_base : 0;
  952. }
  953. void
  954. wasm_runtime_module_free(WASMModuleInstance *module_inst, int32 ptr)
  955. {
  956. uint8 *memory_base = module_inst->default_memory->memory_data;
  957. uint8 *heap_base = module_inst->default_memory->heap_data;
  958. uint32 heap_size = module_inst->default_memory->heap_data_size;
  959. void *heap = module_inst->default_memory->heap_handle;
  960. uint8 *addr = ptr ? memory_base + ptr : NULL;
  961. if (addr && (heap_base < addr && addr < heap_base + heap_size))
  962. mem_allocator_free(heap, addr);
  963. }
  964. int32
  965. wasm_runtime_module_dup_data(WASMModuleInstance *module_inst,
  966. const char *src, uint32 size)
  967. {
  968. int32 buffer_offset = wasm_runtime_module_malloc(module_inst, size);
  969. if (buffer_offset != 0) {
  970. char *buffer;
  971. buffer = wasm_runtime_addr_app_to_native(module_inst, buffer_offset);
  972. memcpy(buffer, src, size);
  973. }
  974. return buffer_offset;
  975. }
  976. bool
  977. wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
  978. int32 app_offset, uint32 size)
  979. {
  980. /* integer overflow check */
  981. if(app_offset < 0 ||
  982. app_offset + size < size) {
  983. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  984. return false;
  985. }
  986. uint8 *memory_base = module_inst->default_memory->memory_data;
  987. uint8 *addr = memory_base + app_offset;
  988. uint8 *base_addr = module_inst->default_memory->base_addr;
  989. uint8 *end_addr = module_inst->default_memory->end_addr;
  990. bool ret = (base_addr <= addr
  991. && addr + size <= end_addr);
  992. if (!ret)
  993. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  994. return ret;
  995. }
  996. bool
  997. wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
  998. void *native_ptr, uint32 size)
  999. {
  1000. uint8 *addr = native_ptr;
  1001. uint8 *base_addr = module_inst->default_memory->base_addr;
  1002. uint8 *end_addr = module_inst->default_memory->end_addr;
  1003. bool ret = (base_addr <= addr && addr + size <= end_addr);
  1004. if (!ret || (addr + size < addr)/* integer overflow */)
  1005. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  1006. return ret;
  1007. }
  1008. void *
  1009. wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst,
  1010. int32 app_offset)
  1011. {
  1012. return module_inst->default_memory->memory_data + app_offset;
  1013. }
  1014. int32
  1015. wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
  1016. void *native_ptr)
  1017. {
  1018. return (uint8*)native_ptr - module_inst->default_memory->memory_data;
  1019. }
  1020. uint32
  1021. wasm_runtime_get_temp_ret(WASMModuleInstance *module_inst)
  1022. {
  1023. return module_inst->temp_ret;
  1024. }
  1025. void
  1026. wasm_runtime_set_temp_ret(WASMModuleInstance *module_inst,
  1027. uint32 temp_ret)
  1028. {
  1029. module_inst->temp_ret = temp_ret;
  1030. }
  1031. uint32
  1032. wasm_runtime_get_llvm_stack(WASMModuleInstance *module_inst)
  1033. {
  1034. return module_inst->llvm_stack;
  1035. }
  1036. void
  1037. wasm_runtime_set_llvm_stack(WASMModuleInstance *module_inst,
  1038. uint32 llvm_stack)
  1039. {
  1040. module_inst->llvm_stack = llvm_stack;
  1041. }
  1042. WASMModuleInstance*
  1043. wasm_runtime_load_aot(uint8 *aot_file, uint32 aot_file_size,
  1044. uint32 heap_size,
  1045. char *error_buf, uint32 error_buf_size)
  1046. {
  1047. (void)aot_file;
  1048. (void)aot_file_size;
  1049. (void)heap_size;
  1050. (void)error_buf;
  1051. (void)error_buf_size;
  1052. return NULL;
  1053. }