wasm_runtime.c 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668
  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 (bh_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. /* Only init stack when no application is running. */
  63. if (!wasm_runtime_get_self()->cur_frame) {
  64. if (!exec_env) {
  65. if (!module_inst->wasm_stack) {
  66. if (!(module_inst->wasm_stack =
  67. wasm_malloc(module_inst->wasm_stack_size))) {
  68. wasm_runtime_set_exception(module_inst,
  69. "allocate memory failed.");
  70. return false;
  71. }
  72. init_wasm_stack(&module_inst->main_tlr.wasm_stack,
  73. module_inst->wasm_stack,
  74. module_inst->wasm_stack_size);
  75. }
  76. }
  77. else {
  78. uintptr_t stack = (uintptr_t)exec_env->stack;
  79. uint32 stack_size;
  80. /* Set to 8 bytes align */
  81. stack = (stack + 7) & ~7;
  82. stack_size = exec_env->stack_size
  83. - (stack - (uintptr_t)exec_env->stack);
  84. if (!exec_env->stack || exec_env->stack_size <= 0
  85. || exec_env->stack_size < stack - (uintptr_t)exec_env->stack) {
  86. wasm_runtime_set_exception(module_inst,
  87. "Invalid execution stack info.");
  88. return false;
  89. }
  90. init_wasm_stack(&module_inst->main_tlr.wasm_stack,
  91. (uint8*)stack, stack_size);
  92. }
  93. }
  94. wasm_interp_call_wasm(function, argc, argv);
  95. return !wasm_runtime_get_exception(module_inst) ? true : false;
  96. }
  97. void
  98. wasm_runtime_set_exception(WASMModuleInstance *module_inst,
  99. const char *exception)
  100. {
  101. if (exception)
  102. snprintf(module_inst->cur_exception,
  103. sizeof(module_inst->cur_exception),
  104. "Exception: %s", exception);
  105. else
  106. module_inst->cur_exception[0] = '\0';
  107. }
  108. const char*
  109. wasm_runtime_get_exception(WASMModuleInstance *module_inst)
  110. {
  111. if (module_inst->cur_exception[0] == '\0')
  112. return NULL;
  113. else
  114. return module_inst->cur_exception;
  115. }
  116. void
  117. wasm_runtime_clear_exception(WASMModuleInstance *module_inst)
  118. {
  119. wasm_runtime_set_exception(module_inst, NULL);
  120. }
  121. WASMModule*
  122. wasm_runtime_load(const uint8 *buf, uint32 size,
  123. char *error_buf, uint32 error_buf_size)
  124. {
  125. return wasm_loader_load(buf, size, error_buf, error_buf_size);
  126. }
  127. WASMModule*
  128. wasm_runtime_load_from_sections(WASMSection *section_list,
  129. char *error_buf, uint32_t error_buf_size)
  130. {
  131. return wasm_loader_load_from_sections(section_list,
  132. error_buf, error_buf_size);
  133. }
  134. void
  135. wasm_runtime_unload(WASMModule *module)
  136. {
  137. wasm_loader_unload(module);
  138. }
  139. /**
  140. * Destroy memory instances.
  141. */
  142. static void
  143. memories_deinstantiate(WASMMemoryInstance **memories, uint32 count)
  144. {
  145. uint32 i;
  146. if (memories) {
  147. for (i = 0; i < count; i++)
  148. if (memories[i]) {
  149. if (memories[i]->heap_handle)
  150. mem_allocator_destroy(memories[i]->heap_handle);
  151. wasm_free(memories[i]->heap_data);
  152. wasm_free(memories[i]);
  153. }
  154. wasm_free(memories);
  155. }
  156. }
  157. static WASMMemoryInstance*
  158. memory_instantiate(uint32 init_page_count, uint32 max_page_count,
  159. uint32 addr_data_size, uint32 global_data_size,
  160. uint32 heap_size,
  161. char *error_buf, uint32 error_buf_size)
  162. {
  163. WASMMemoryInstance *memory;
  164. uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
  165. NumBytesPerPage * init_page_count +
  166. addr_data_size + global_data_size;
  167. /* Allocate memory space, addr data and global data */
  168. if (!(memory = wasm_malloc(total_size))) {
  169. set_error_buf(error_buf, error_buf_size,
  170. "Instantiate memory failed: allocate memory failed.");
  171. return NULL;
  172. }
  173. memset(memory, 0, total_size);
  174. memory->cur_page_count = init_page_count;
  175. memory->max_page_count = max_page_count;
  176. memory->addr_data = memory->base_addr;
  177. memory->addr_data_size = addr_data_size;
  178. memory->memory_data = memory->addr_data + addr_data_size;
  179. memory->global_data = memory->memory_data +
  180. NumBytesPerPage * memory->cur_page_count;;
  181. memory->global_data_size = global_data_size;
  182. memory->end_addr = memory->global_data + global_data_size;
  183. /* Allocate heap space */
  184. if (!(memory->heap_data = wasm_malloc(heap_size))) {
  185. set_error_buf(error_buf, error_buf_size,
  186. "Instantiate memory failed: allocate memory failed.");
  187. goto fail1;
  188. }
  189. memory->heap_data_end = memory->heap_data + heap_size;
  190. /* Initialize heap */
  191. if (!(memory->heap_handle = mem_allocator_create
  192. (memory->heap_data, heap_size))) {
  193. goto fail2;
  194. }
  195. #if WASM_ENABLE_MEMORY_GROW != 0
  196. memory->heap_base_offset = DEFAULT_APP_HEAP_BASE_OFFSET;
  197. #else
  198. memory->heap_base_offset = memory->end_addr - memory->memory_data;
  199. #endif
  200. return memory;
  201. fail2:
  202. wasm_free(memory->heap_data);
  203. fail1:
  204. wasm_free(memory);
  205. return NULL;
  206. }
  207. /**
  208. * Instantiate memories in a module.
  209. */
  210. static WASMMemoryInstance**
  211. memories_instantiate(const WASMModule *module, uint32 addr_data_size,
  212. uint32 global_data_size, uint32 heap_size,
  213. char *error_buf, uint32 error_buf_size)
  214. {
  215. WASMImport *import;
  216. uint32 mem_index = 0, i, memory_count =
  217. module->import_memory_count + module->memory_count;
  218. uint32 total_size;
  219. WASMMemoryInstance **memories, *memory;
  220. if (memory_count == 0 && global_data_size > 0)
  221. memory_count = 1;
  222. total_size = sizeof(WASMMemoryInstance*) * memory_count;
  223. memories = wasm_malloc(total_size);
  224. if (!memories) {
  225. set_error_buf(error_buf, error_buf_size,
  226. "Instantiate memory failed: "
  227. "allocate memory failed.");
  228. return NULL;
  229. }
  230. memset(memories, 0, total_size);
  231. /* instantiate memories from import section */
  232. import = module->import_memories;
  233. for (i = 0; i < module->import_memory_count; i++, import++) {
  234. if (!(memory = memories[mem_index++] =
  235. memory_instantiate(import->u.memory.init_page_count,
  236. import->u.memory. max_page_count,
  237. addr_data_size, global_data_size,
  238. heap_size, error_buf, error_buf_size))) {
  239. set_error_buf(error_buf, error_buf_size,
  240. "Instantiate memory failed: "
  241. "allocate memory failed.");
  242. memories_deinstantiate(memories, memory_count);
  243. return NULL;
  244. }
  245. }
  246. /* instantiate memories from memory section */
  247. for (i = 0; i < module->memory_count; i++) {
  248. if (!(memory = memories[mem_index++] =
  249. memory_instantiate(module->memories[i].init_page_count,
  250. module->memories[i].max_page_count,
  251. addr_data_size, global_data_size,
  252. heap_size, error_buf, error_buf_size))) {
  253. set_error_buf(error_buf, error_buf_size,
  254. "Instantiate memory failed: "
  255. "allocate memory failed.");
  256. memories_deinstantiate(memories, memory_count);
  257. return NULL;
  258. }
  259. }
  260. if (mem_index == 0) {
  261. /* no import memory and define memory, but has global variables */
  262. if (!(memory = memories[mem_index++] =
  263. memory_instantiate(0, 0, addr_data_size, global_data_size,
  264. heap_size, error_buf, error_buf_size))) {
  265. set_error_buf(error_buf, error_buf_size,
  266. "Instantiate memory failed: "
  267. "allocate memory failed.\n");
  268. memories_deinstantiate(memories, memory_count);
  269. return NULL;
  270. }
  271. }
  272. wasm_assert(mem_index == memory_count);
  273. return memories;
  274. }
  275. /**
  276. * Destroy table instances.
  277. */
  278. static void
  279. tables_deinstantiate(WASMTableInstance **tables, uint32 count)
  280. {
  281. uint32 i;
  282. if (tables) {
  283. for (i = 0; i < count; i++)
  284. if (tables[i])
  285. wasm_free(tables[i]);
  286. wasm_free(tables);
  287. }
  288. }
  289. /**
  290. * Instantiate tables in a module.
  291. */
  292. static WASMTableInstance**
  293. tables_instantiate(const WASMModule *module,
  294. char *error_buf, uint32 error_buf_size)
  295. {
  296. WASMImport *import;
  297. uint32 table_index = 0, i, table_count =
  298. module->import_table_count + module->table_count;
  299. uint32 total_size = sizeof(WASMTableInstance*) * table_count;
  300. WASMTableInstance **tables = wasm_malloc(total_size), *table;
  301. if (!tables) {
  302. set_error_buf(error_buf, error_buf_size,
  303. "Instantiate table failed: "
  304. "allocate memory failed.");
  305. return NULL;
  306. }
  307. memset(tables, 0, total_size);
  308. /* instantiate tables from import section */
  309. import = module->import_tables;
  310. for (i = 0; i < module->import_table_count; i++, import++) {
  311. total_size = offsetof(WASMTableInstance, base_addr) +
  312. sizeof(uint32) * import->u.table.init_size;
  313. if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
  314. set_error_buf(error_buf, error_buf_size,
  315. "Instantiate table failed: "
  316. "allocate memory failed.");
  317. tables_deinstantiate(tables, table_count);
  318. return NULL;
  319. }
  320. memset(table, 0, total_size);
  321. table->cur_size = import->u.table.init_size;
  322. table->max_size = import->u.table.max_size;
  323. }
  324. /* instantiate tables from table section */
  325. for (i = 0; i < module->table_count; i++) {
  326. total_size = offsetof(WASMTableInstance, base_addr) +
  327. sizeof(uint32) * module->tables[i].init_size;
  328. if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
  329. set_error_buf(error_buf, error_buf_size,
  330. "Instantiate table failed: "
  331. "allocate memory failed.");
  332. tables_deinstantiate(tables, table_count);
  333. return NULL;
  334. }
  335. memset(table, 0, total_size);
  336. table->cur_size = module->tables[i].init_size;
  337. table->max_size = module->tables[i].max_size;
  338. }
  339. wasm_assert(table_index == table_count);
  340. return tables;
  341. }
  342. /**
  343. * Destroy function instances.
  344. */
  345. static void
  346. functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
  347. {
  348. if (functions) {
  349. uint32 i;
  350. for (i = 0; i < count; i++)
  351. if (functions[i].local_offsets)
  352. wasm_free(functions[i].local_offsets);
  353. wasm_free(functions);
  354. }
  355. }
  356. static bool
  357. function_init_local_offsets(WASMFunctionInstance *func)
  358. {
  359. uint16 local_offset = 0;
  360. WASMType *param_type = func->u.func->func_type;
  361. uint32 param_count = param_type->param_count;
  362. uint8 *param_types = param_type->types;
  363. uint32 local_count = func->u.func->local_count;
  364. uint8 *local_types = func->u.func->local_types;
  365. uint32 i, total_size = (param_count + local_count) * sizeof(uint16);
  366. if (!(func->local_offsets = wasm_malloc(total_size)))
  367. return false;
  368. for (i = 0; i < param_count; i++) {
  369. func->local_offsets[i] = local_offset;
  370. local_offset += wasm_value_type_cell_num(param_types[i]);
  371. }
  372. for (i = 0; i < local_count; i++) {
  373. func->local_offsets[param_count + i] = local_offset;
  374. local_offset += wasm_value_type_cell_num(local_types[i]);
  375. }
  376. wasm_assert(local_offset == func->param_cell_num + func->local_cell_num);
  377. return true;
  378. }
  379. /**
  380. * Instantiate functions in a module.
  381. */
  382. static WASMFunctionInstance*
  383. functions_instantiate(const WASMModule *module,
  384. char *error_buf, uint32 error_buf_size)
  385. {
  386. WASMImport *import;
  387. uint32 i, function_count =
  388. module->import_function_count + module->function_count;
  389. uint32 total_size = sizeof(WASMFunctionInstance) * function_count;
  390. WASMFunctionInstance *functions = wasm_malloc(total_size), *function;
  391. if (!functions) {
  392. set_error_buf(error_buf, error_buf_size,
  393. "Instantiate function failed: "
  394. "allocate memory failed.");
  395. return NULL;
  396. }
  397. memset(functions, 0, total_size);
  398. /* instantiate functions from import section */
  399. function = functions;
  400. import = module->import_functions;
  401. for (i = 0; i < module->import_function_count; i++, import++) {
  402. function->is_import_func = true;
  403. function->u.func_import = &import->u.function;
  404. function->param_cell_num =
  405. wasm_type_param_cell_num(import->u.function.func_type);
  406. function->ret_cell_num =
  407. wasm_type_return_cell_num(import->u.function.func_type);
  408. function->local_cell_num = 0;
  409. function++;
  410. }
  411. /* instantiate functions from function section */
  412. for (i = 0; i < module->function_count; i++) {
  413. function->is_import_func = false;
  414. function->u.func = module->functions[i];
  415. function->param_cell_num =
  416. wasm_type_param_cell_num(function->u.func->func_type);
  417. function->ret_cell_num =
  418. wasm_type_return_cell_num(function->u.func->func_type);
  419. function->local_cell_num =
  420. wasm_get_cell_num(function->u.func->local_types,
  421. function->u.func->local_count);
  422. if (!function_init_local_offsets(function)) {
  423. functions_deinstantiate(functions, function_count);
  424. return NULL;
  425. }
  426. function++;
  427. }
  428. wasm_assert((uint32)(function - functions) == function_count);
  429. return functions;
  430. }
  431. /**
  432. * Destroy global instances.
  433. */
  434. static void
  435. globals_deinstantiate(WASMGlobalInstance *globals)
  436. {
  437. if (globals)
  438. wasm_free(globals);
  439. }
  440. /**
  441. * Instantiate globals in a module.
  442. */
  443. static WASMGlobalInstance*
  444. globals_instantiate(const WASMModule *module,
  445. uint32 *p_addr_data_size,
  446. uint32 *p_global_data_size,
  447. char *error_buf, uint32 error_buf_size)
  448. {
  449. WASMImport *import;
  450. uint32 addr_data_offset = 0, global_data_offset = 0;
  451. uint32 i, global_count =
  452. module->import_global_count + module->global_count;
  453. uint32 total_size = sizeof(WASMGlobalInstance) * global_count;
  454. WASMGlobalInstance *globals = wasm_malloc(total_size), *global;
  455. if (!globals) {
  456. set_error_buf(error_buf, error_buf_size,
  457. "Instantiate global failed: "
  458. "allocate memory failed.");
  459. return NULL;
  460. }
  461. memset(globals, 0, total_size);
  462. /* instantiate globals from import section */
  463. global = globals;
  464. import = module->import_globals;
  465. for (i = 0; i < module->import_global_count; i++, import++) {
  466. WASMGlobalImport *global_import = &import->u.global;
  467. global->type = global_import->type;
  468. global->is_mutable = global_import->is_mutable;
  469. global->is_addr = global_import->is_addr;
  470. global->initial_value = global_import->global_data_linked;
  471. global->data_offset = global_data_offset;
  472. global_data_offset += wasm_value_type_size(global->type);
  473. if (global->is_addr)
  474. addr_data_offset += sizeof(uint32);
  475. global++;
  476. }
  477. /* instantiate globals from global section */
  478. for (i = 0; i < module->global_count; i++) {
  479. global->type = module->globals[i].type;
  480. global->is_mutable = module->globals[i].is_mutable;
  481. global->is_addr = module->globals[i].is_addr;
  482. global->data_offset = global_data_offset;
  483. global_data_offset += wasm_value_type_size(global->type);
  484. if (global->is_addr)
  485. addr_data_offset += sizeof(uint32);
  486. global++;
  487. }
  488. wasm_assert((uint32)(global - globals) == global_count);
  489. *p_addr_data_size = addr_data_offset;
  490. *p_global_data_size = global_data_offset;
  491. return globals;
  492. }
  493. static void
  494. globals_instantiate_fix(WASMGlobalInstance *globals,
  495. const WASMModule *module,
  496. WASMModuleInstance *module_inst)
  497. {
  498. WASMGlobalInstance *global = globals;
  499. WASMImport *import = module->import_globals;
  500. uint32 i;
  501. /* Fix globals from import section */
  502. for (i = 0; i < module->import_global_count; i++, import++, global++) {
  503. if (!strcmp(import->u.names.module_name, "env")) {
  504. if (!strcmp(import->u.names.field_name, "memoryBase")
  505. || !strcmp(import->u.names.field_name, "__memory_base")) {
  506. global->initial_value.addr = 0;
  507. }
  508. else if (!strcmp(import->u.names.field_name, "tableBase")
  509. || !strcmp(import->u.names.field_name, "__table_base")) {
  510. global->initial_value.addr = 0;
  511. }
  512. else if (!strcmp(import->u.names.field_name, "DYNAMICTOP_PTR")) {
  513. global->initial_value.i32 =
  514. NumBytesPerPage * module_inst->default_memory->cur_page_count;
  515. module_inst->DYNAMICTOP_PTR_offset = global->data_offset;
  516. }
  517. else if (!strcmp(import->u.names.field_name, "STACKTOP")) {
  518. global->initial_value.i32 = 0;
  519. }
  520. else if (!strcmp(import->u.names.field_name, "STACK_MAX")) {
  521. /* Unused in emcc wasm bin actually. */
  522. global->initial_value.i32 = 0;
  523. }
  524. }
  525. }
  526. for (i = 0; i < module->global_count; i++) {
  527. InitializerExpression *init_expr = &module->globals[i].init_expr;
  528. if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  529. wasm_assert(init_expr->u.global_index < module->import_global_count);
  530. global->initial_value = globals[init_expr->u.global_index].initial_value;
  531. }
  532. else {
  533. memcpy(&global->initial_value, &init_expr->u, sizeof(int64));
  534. }
  535. global++;
  536. }
  537. }
  538. /**
  539. * Return export function count in module export section.
  540. */
  541. static uint32
  542. get_export_function_count(const WASMModule *module)
  543. {
  544. WASMExport *export = module->exports;
  545. uint32 count = 0, i;
  546. for (i = 0; i < module->export_count; i++, export++)
  547. if (export->kind == EXPORT_KIND_FUNC)
  548. count++;
  549. return count;
  550. }
  551. /**
  552. * Destroy export function instances.
  553. */
  554. static void
  555. export_functions_deinstantiate(WASMExportFuncInstance *functions)
  556. {
  557. if (functions)
  558. wasm_free(functions);
  559. }
  560. /**
  561. * Instantiate export functions in a module.
  562. */
  563. static WASMExportFuncInstance*
  564. export_functions_instantiate(const WASMModule *module,
  565. WASMModuleInstance *module_inst,
  566. uint32 export_func_count,
  567. char *error_buf, uint32 error_buf_size)
  568. {
  569. WASMExportFuncInstance *export_funcs, *export_func;
  570. WASMExport *export = module->exports;
  571. uint32 i, total_size = sizeof(WASMExportFuncInstance) * export_func_count;
  572. if (!(export_func = export_funcs = wasm_malloc(total_size))) {
  573. set_error_buf(error_buf, error_buf_size,
  574. "Instantiate export function failed: "
  575. "allocate memory failed.");
  576. return NULL;
  577. }
  578. memset(export_funcs, 0, total_size);
  579. for (i = 0; i < module->export_count; i++, export++)
  580. if (export->kind == EXPORT_KIND_FUNC) {
  581. wasm_assert(export->index >= module->import_function_count
  582. && export->index < module->import_function_count
  583. + module->function_count);
  584. export_func->name = export->name;
  585. export_func->function = &module_inst->functions[export->index];
  586. export_func++;
  587. }
  588. wasm_assert((uint32)(export_func - export_funcs) == export_func_count);
  589. return export_funcs;
  590. }
  591. void
  592. wasm_runtime_deinstantiate(WASMModuleInstance *module_inst);
  593. static bool
  594. execute_post_inst_function(WASMModuleInstance *module_inst)
  595. {
  596. WASMFunctionInstance *post_inst_func = NULL;
  597. WASMType *post_inst_func_type;
  598. uint32 i;
  599. for (i = 0; i < module_inst->export_func_count; i++)
  600. if (!strcmp(module_inst->export_functions[i].name, "__post_instantiate")) {
  601. post_inst_func = module_inst->export_functions[i].function;
  602. break;
  603. }
  604. if (!post_inst_func)
  605. /* Not found */
  606. return true;
  607. post_inst_func_type = post_inst_func->u.func->func_type;
  608. if (post_inst_func_type->param_count != 0
  609. || post_inst_func_type->result_count != 0)
  610. /* Not a valid function type, ignore it */
  611. return true;
  612. return wasm_runtime_call_wasm(module_inst, NULL, post_inst_func, 0, NULL);
  613. }
  614. static bool
  615. execute_start_function(WASMModuleInstance *module_inst)
  616. {
  617. WASMFunctionInstance *func = module_inst->start_function;
  618. if (!func)
  619. return true;
  620. wasm_assert(!func->is_import_func && func->param_cell_num == 0
  621. && func->ret_cell_num == 0);
  622. return wasm_runtime_call_wasm(module_inst, NULL, func, 0, NULL);
  623. }
  624. /**
  625. * Instantiate module
  626. */
  627. WASMModuleInstance*
  628. wasm_runtime_instantiate(WASMModule *module,
  629. uint32 stack_size, uint32 heap_size,
  630. char *error_buf, uint32 error_buf_size)
  631. {
  632. WASMModuleInstance *module_inst;
  633. WASMTableSeg *table_seg;
  634. WASMDataSeg *data_seg;
  635. WASMGlobalInstance *globals = NULL, *global;
  636. uint32 global_count, addr_data_size = 0, global_data_size = 0, i;
  637. uint32 base_offset, length, memory_size;
  638. uint8 *global_data, *global_data_end, *addr_data, *addr_data_end;
  639. uint8 *memory_data;
  640. uint32 *table_data;
  641. if (!module)
  642. return NULL;
  643. /* Check heap size */
  644. heap_size = align_uint(heap_size, 8);
  645. if (heap_size == 0)
  646. heap_size = APP_HEAP_SIZE_DEFAULT;
  647. if (heap_size < APP_HEAP_SIZE_MIN)
  648. heap_size = APP_HEAP_SIZE_MIN;
  649. if (heap_size > APP_HEAP_SIZE_MAX)
  650. heap_size = APP_HEAP_SIZE_MAX;
  651. /* Instantiate global firstly to get the mutable data size */
  652. global_count = module->import_global_count + module->global_count;
  653. if (global_count &&
  654. !(globals = globals_instantiate(module, &addr_data_size,
  655. &global_data_size,
  656. error_buf, error_buf_size)))
  657. return NULL;
  658. /* Allocate the memory */
  659. if (!(module_inst = wasm_malloc(sizeof(WASMModuleInstance)))) {
  660. set_error_buf(error_buf, error_buf_size,
  661. "Instantiate module failed: allocate memory failed.");
  662. globals_deinstantiate(globals);
  663. return NULL;
  664. }
  665. memset(module_inst, 0, sizeof(WASMModuleInstance));
  666. module_inst->global_count = global_count;
  667. module_inst->globals = globals;
  668. module_inst->memory_count =
  669. module->import_memory_count + module->memory_count;
  670. module_inst->table_count =
  671. module->import_table_count + module->table_count;
  672. module_inst->function_count =
  673. module->import_function_count + module->function_count;
  674. module_inst->export_func_count = get_export_function_count(module);
  675. /* Instantiate memories/tables/functions */
  676. if (((module_inst->memory_count > 0 || global_count > 0)
  677. && !(module_inst->memories =
  678. memories_instantiate(module, addr_data_size, global_data_size,
  679. heap_size, error_buf, error_buf_size)))
  680. || (module_inst->table_count > 0
  681. && !(module_inst->tables = tables_instantiate(module,
  682. error_buf,
  683. error_buf_size)))
  684. || (module_inst->function_count > 0
  685. && !(module_inst->functions = functions_instantiate(module,
  686. error_buf,
  687. error_buf_size)))
  688. || (module_inst->export_func_count > 0
  689. && !(module_inst->export_functions = export_functions_instantiate(
  690. module, module_inst, module_inst->export_func_count,
  691. error_buf, error_buf_size)))) {
  692. wasm_runtime_deinstantiate(module_inst);
  693. return NULL;
  694. }
  695. if (module_inst->memory_count || global_count > 0) {
  696. WASMMemoryInstance *memory;
  697. memory = module_inst->default_memory = module_inst->memories[0];
  698. memory_data = module_inst->default_memory->memory_data;
  699. /* fix import memoryBase */
  700. globals_instantiate_fix(globals, module, module_inst);
  701. /* Initialize the global data */
  702. addr_data = memory->addr_data;
  703. addr_data_end = addr_data + addr_data_size;
  704. global_data = memory->global_data;
  705. global_data_end = global_data + global_data_size;
  706. global = globals;
  707. for (i = 0; i < global_count; i++, global++) {
  708. switch (global->type) {
  709. case VALUE_TYPE_I32:
  710. case VALUE_TYPE_F32:
  711. if (!global->is_addr)
  712. *(int32*)global_data = global->initial_value.i32;
  713. else {
  714. *(int32*)addr_data = global->initial_value.i32;
  715. /* Store the offset to memory data for global of addr */
  716. *(int32*)global_data = addr_data - memory_data;
  717. addr_data += sizeof(int32);
  718. }
  719. global_data += sizeof(int32);
  720. break;
  721. case VALUE_TYPE_I64:
  722. case VALUE_TYPE_F64:
  723. wasm_assert(!global->is_addr);
  724. memcpy(global_data, &global->initial_value.i64, sizeof(int64));
  725. global_data += sizeof(int64);
  726. break;
  727. default:
  728. wasm_assert(0);
  729. }
  730. }
  731. wasm_assert(addr_data == addr_data_end);
  732. wasm_assert(global_data == global_data_end);
  733. global = globals + module->import_global_count;
  734. for (i = 0; i < module->global_count; i++, global++) {
  735. InitializerExpression *init_expr = &module->globals[i].init_expr;
  736. if (init_expr->init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL
  737. && globals[init_expr->u.global_index].is_addr) {
  738. uint8 *global_data_dst = memory->global_data + global->data_offset;
  739. uint8 *global_data_src =
  740. memory->global_data + globals[init_expr->u.global_index].data_offset;
  741. *(uintptr_t*)global_data_dst = *(uintptr_t*)global_data_src;
  742. }
  743. }
  744. /* Initialize the memory data with data segment section */
  745. if (module_inst->default_memory->cur_page_count > 0) {
  746. for (i = 0; i < module->data_seg_count; i++) {
  747. data_seg = module->data_segments[i];
  748. wasm_assert(data_seg->memory_index == 0);
  749. wasm_assert(data_seg->base_offset.init_expr_type ==
  750. INIT_EXPR_TYPE_I32_CONST
  751. || data_seg->base_offset.init_expr_type ==
  752. INIT_EXPR_TYPE_GET_GLOBAL);
  753. if (data_seg->base_offset.init_expr_type == INIT_EXPR_TYPE_GET_GLOBAL) {
  754. wasm_assert(data_seg->base_offset.u.global_index < global_count
  755. && globals[data_seg->base_offset.u.global_index].type ==
  756. VALUE_TYPE_I32);
  757. data_seg->base_offset.u.i32 =
  758. globals[data_seg->base_offset.u.global_index].initial_value.i32;
  759. }
  760. base_offset = (uint32)data_seg->base_offset.u.i32;
  761. length = data_seg->data_length;
  762. memory_size = NumBytesPerPage * module_inst->default_memory->cur_page_count;
  763. if (length > 0
  764. && (base_offset >= memory_size
  765. || base_offset + length > memory_size)) {
  766. set_error_buf(error_buf, error_buf_size,
  767. "Instantiate module failed: data segment out of range.");
  768. wasm_runtime_deinstantiate(module_inst);
  769. return NULL;
  770. }
  771. memcpy(memory_data + base_offset, data_seg->data, length);
  772. }
  773. }
  774. }
  775. if (module_inst->table_count) {
  776. module_inst->default_table = module_inst->tables[0];
  777. /* Initialize the table data with table segment section */
  778. table_data = (uint32*)module_inst->default_table->base_addr;
  779. table_seg = module->table_segments;
  780. for (i = 0; i < module->table_seg_count; i++, table_seg++) {
  781. wasm_assert(table_seg->table_index == 0);
  782. wasm_assert(table_seg->base_offset.init_expr_type ==
  783. INIT_EXPR_TYPE_I32_CONST
  784. || table_seg->base_offset.init_expr_type ==
  785. INIT_EXPR_TYPE_GET_GLOBAL);
  786. if (table_seg->base_offset.init_expr_type ==
  787. INIT_EXPR_TYPE_GET_GLOBAL) {
  788. wasm_assert(table_seg->base_offset.u.global_index < global_count
  789. && globals[table_seg->base_offset.u.global_index].type ==
  790. VALUE_TYPE_I32);
  791. table_seg->base_offset.u.i32 =
  792. globals[table_seg->base_offset.u.global_index].initial_value.i32;
  793. }
  794. if ((uint32)table_seg->base_offset.u.i32 <
  795. module_inst->default_table->cur_size) {
  796. length = table_seg->function_count;
  797. if (table_seg->base_offset.u.i32 + length >
  798. module_inst->default_table->cur_size)
  799. length = module_inst->default_table->cur_size
  800. - table_seg->base_offset.u.i32;
  801. memcpy(table_data + table_seg->base_offset.u.i32,
  802. table_seg->func_indexes, length * sizeof(uint32));
  803. }
  804. }
  805. }
  806. if (module->start_function != (uint32)-1) {
  807. wasm_assert(module->start_function >= module->import_function_count);
  808. module_inst->start_function =
  809. &module_inst->functions[module->start_function];
  810. }
  811. module_inst->module = module;
  812. /* module instance type */
  813. module_inst->module_type = Wasm_Module_Bytecode;
  814. /* Initialize the thread related data */
  815. if (stack_size == 0)
  816. stack_size = DEFAULT_WASM_STACK_SIZE;
  817. module_inst->wasm_stack_size = stack_size;
  818. module_inst->main_tlr.module_inst = module_inst;
  819. /* Bind thread data with current native thread:
  820. set thread local root to current thread. */
  821. wasm_runtime_set_tlr(&module_inst->main_tlr);
  822. module_inst->main_tlr.handle = ws_self_thread();
  823. /* Execute __post_instantiate and start function */
  824. if (!execute_post_inst_function(module_inst)
  825. || !execute_start_function(module_inst)) {
  826. set_error_buf(error_buf, error_buf_size,
  827. module_inst->cur_exception);
  828. wasm_runtime_deinstantiate(module_inst);
  829. return NULL;
  830. }
  831. (void)addr_data_end;
  832. (void)global_data_end;
  833. return module_inst;
  834. }
  835. void
  836. wasm_runtime_deinstantiate(WASMModuleInstance *module_inst)
  837. {
  838. if (!module_inst)
  839. return;
  840. if (module_inst->memory_count > 0)
  841. memories_deinstantiate(module_inst->memories, module_inst->memory_count);
  842. else if (module_inst->memories != NULL && module_inst->global_count > 0)
  843. /* No imported memory and defined memory, the memory is created when
  844. global count > 0. */
  845. memories_deinstantiate(module_inst->memories, 1);
  846. tables_deinstantiate(module_inst->tables, module_inst->table_count);
  847. functions_deinstantiate(module_inst->functions, module_inst->function_count);
  848. globals_deinstantiate(module_inst->globals);
  849. export_functions_deinstantiate(module_inst->export_functions);
  850. if (module_inst->wasm_stack)
  851. wasm_free(module_inst->wasm_stack);
  852. wasm_free(module_inst);
  853. }
  854. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  855. bool
  856. wasm_runtime_set_ext_memory(WASMModuleInstance *module_inst,
  857. uint8 *ext_mem_data, uint32 ext_mem_size,
  858. char *error_buf, uint32 error_buf_size)
  859. {
  860. if (module_inst->ext_mem_data) {
  861. set_error_buf(error_buf, error_buf_size,
  862. "Set external memory failed: "
  863. "an external memory has been set.");
  864. return false;
  865. }
  866. if (!ext_mem_data
  867. || ext_mem_size > 1 * BH_GB
  868. || ext_mem_data + ext_mem_size < ext_mem_data) {
  869. set_error_buf(error_buf, error_buf_size,
  870. "Set external memory failed: "
  871. "invalid input.");
  872. return false;
  873. }
  874. module_inst->ext_mem_data = ext_mem_data;
  875. module_inst->ext_mem_data_end = ext_mem_data + ext_mem_size;
  876. module_inst->ext_mem_size = ext_mem_size;
  877. module_inst->ext_mem_base_offset = DEFAULT_EXT_MEM_BASE_OFFSET;
  878. return true;
  879. }
  880. #endif
  881. bool
  882. wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
  883. {
  884. #if WASM_ENABLE_MEMORY_GROW != 0
  885. WASMMemoryInstance *memory = module->default_memory;
  886. WASMMemoryInstance *new_memory;
  887. uint32 total_page_count = inc_page_count + memory->cur_page_count;
  888. uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
  889. memory->addr_data_size +
  890. NumBytesPerPage * total_page_count +
  891. memory->global_data_size;
  892. if (inc_page_count <= 0)
  893. /* No need to enlarge memory */
  894. return true;
  895. if (total_page_count < memory->cur_page_count /* integer overflow */
  896. || total_page_count > memory->max_page_count) {
  897. wasm_runtime_set_exception(module, "fail to enlarge memory.");
  898. return false;
  899. }
  900. if (!(new_memory = wasm_malloc(total_size))) {
  901. wasm_runtime_set_exception(module, "fail to enlarge memory.");
  902. return false;
  903. }
  904. new_memory->cur_page_count = total_page_count;
  905. new_memory->max_page_count = memory->max_page_count;
  906. new_memory->addr_data = new_memory->base_addr;
  907. new_memory->addr_data_size = memory->addr_data_size;
  908. new_memory->memory_data = new_memory->addr_data + new_memory->addr_data_size;
  909. new_memory->global_data = new_memory->memory_data +
  910. NumBytesPerPage * total_page_count;
  911. new_memory->global_data_size = memory->global_data_size;
  912. new_memory->end_addr = new_memory->global_data + memory->global_data_size;
  913. /* Copy addr data and memory data */
  914. memcpy(new_memory->addr_data, memory->addr_data,
  915. memory->global_data - memory->addr_data);
  916. /* Copy global data */
  917. memcpy(new_memory->global_data, memory->global_data,
  918. memory->global_data_size);
  919. /* Init free space of new memory */
  920. memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count,
  921. 0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
  922. new_memory->heap_data = memory->heap_data;
  923. new_memory->heap_data_end = memory->heap_data_end;
  924. new_memory->heap_handle = memory->heap_handle;
  925. new_memory->heap_base_offset = memory->heap_base_offset;
  926. module->memories[0] = module->default_memory = new_memory;
  927. wasm_free(memory);
  928. return true;
  929. #else
  930. wasm_runtime_set_exception(module, "unsupported operation: enlarge memory.");
  931. return false;
  932. #endif
  933. }
  934. PackageType
  935. get_package_type(const uint8 *buf, uint32 size)
  936. {
  937. if (buf && size > 4) {
  938. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 's' && buf[3] == 'm')
  939. return Wasm_Module_Bytecode;
  940. if (buf[0] == '\0' && buf[1] == 'a' && buf[2] == 'o' && buf[3] == 't')
  941. return Wasm_Module_AoT;
  942. }
  943. return Package_Type_Unknown;
  944. }
  945. WASMExecEnv*
  946. wasm_runtime_create_exec_env(uint32 stack_size)
  947. {
  948. WASMExecEnv *exec_env = wasm_malloc(sizeof(WASMExecEnv));
  949. if (exec_env) {
  950. if (!(exec_env->stack = wasm_malloc(stack_size))) {
  951. wasm_free(exec_env);
  952. return NULL;
  953. }
  954. exec_env->stack_size = stack_size;
  955. }
  956. return exec_env;
  957. }
  958. void
  959. wasm_runtime_destroy_exec_env(WASMExecEnv *env)
  960. {
  961. if (env) {
  962. wasm_free(env->stack);
  963. wasm_free(env);
  964. }
  965. }
  966. bool
  967. wasm_runtime_attach_current_thread(WASMModuleInstance *module_inst,
  968. void *thread_data)
  969. {
  970. wasm_runtime_set_tlr(&module_inst->main_tlr);
  971. module_inst->main_tlr.handle = ws_self_thread();
  972. module_inst->thread_data = thread_data;
  973. return true;
  974. }
  975. void
  976. wasm_runtime_detach_current_thread(WASMModuleInstance *module_inst)
  977. {
  978. module_inst->thread_data = NULL;
  979. }
  980. void*
  981. wasm_runtime_get_current_thread_data()
  982. {
  983. WASMThread *tlr = wasm_runtime_get_self();
  984. return (tlr && tlr->module_inst) ? tlr->module_inst->thread_data : NULL;
  985. }
  986. WASMModuleInstance *
  987. wasm_runtime_get_current_module_inst()
  988. {
  989. WASMThread *tlr = wasm_runtime_get_self();
  990. return tlr ? tlr->module_inst : NULL;
  991. }
  992. int32
  993. wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size)
  994. {
  995. WASMMemoryInstance *memory = module_inst->default_memory;
  996. uint8 *addr = mem_allocator_malloc(memory->heap_handle, size);
  997. if (!addr) {
  998. wasm_runtime_set_exception(module_inst, "out of memory");
  999. return 0;
  1000. }
  1001. return memory->heap_base_offset + (addr - memory->heap_data);
  1002. }
  1003. void
  1004. wasm_runtime_module_free(WASMModuleInstance *module_inst, int32 ptr)
  1005. {
  1006. if (ptr) {
  1007. WASMMemoryInstance *memory = module_inst->default_memory;
  1008. uint8 *addr = memory->heap_data + (ptr - memory->heap_base_offset);
  1009. if (memory->heap_data < addr && addr < memory->heap_data_end)
  1010. mem_allocator_free(memory->heap_handle, addr);
  1011. }
  1012. }
  1013. int32
  1014. wasm_runtime_module_dup_data(WASMModuleInstance *module_inst,
  1015. const char *src, uint32 size)
  1016. {
  1017. int32 buffer_offset = wasm_runtime_module_malloc(module_inst, size);
  1018. if (buffer_offset != 0) {
  1019. char *buffer;
  1020. buffer = wasm_runtime_addr_app_to_native(module_inst, buffer_offset);
  1021. memcpy(buffer, src, size);
  1022. }
  1023. return buffer_offset;
  1024. }
  1025. bool
  1026. wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
  1027. int32 app_offset, uint32 size)
  1028. {
  1029. WASMMemoryInstance *memory;
  1030. uint8 *addr;
  1031. /* integer overflow check */
  1032. if(app_offset + size < app_offset) {
  1033. goto fail;
  1034. }
  1035. memory = module_inst->default_memory;
  1036. if (0 <= app_offset
  1037. && app_offset < memory->heap_base_offset) {
  1038. addr = memory->memory_data + app_offset;
  1039. if (!(memory->base_addr <= addr && addr + size <= memory->end_addr))
  1040. goto fail;
  1041. return true;
  1042. }
  1043. else if (memory->heap_base_offset < app_offset
  1044. && app_offset < memory->heap_base_offset
  1045. + (memory->heap_data_end - memory->heap_data)) {
  1046. addr = memory->heap_data + (app_offset - memory->heap_base_offset);
  1047. if (!(memory->heap_data <= addr && addr + size <= memory->heap_data_end))
  1048. goto fail;
  1049. return true;
  1050. }
  1051. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  1052. else if (module_inst->ext_mem_data
  1053. && module_inst->ext_mem_base_offset <= app_offset
  1054. && app_offset < module_inst->ext_mem_base_offset
  1055. + module_inst->ext_mem_size) {
  1056. addr = module_inst->ext_mem_data
  1057. + (app_offset - module_inst->ext_mem_base_offset);
  1058. if (!(module_inst->ext_mem_data <= addr
  1059. && addr + size <= module_inst->ext_mem_data_end))
  1060. goto fail;
  1061. return true;
  1062. }
  1063. #endif
  1064. fail:
  1065. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  1066. return false;
  1067. }
  1068. bool
  1069. wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
  1070. void *native_ptr, uint32 size)
  1071. {
  1072. uint8 *addr = native_ptr;
  1073. WASMMemoryInstance *memory = module_inst->default_memory;
  1074. if (addr + size < addr) {
  1075. goto fail;
  1076. }
  1077. if ((memory->base_addr <= addr && addr + size <= memory->end_addr)
  1078. || (memory->heap_data <= addr && addr + size <= memory->heap_data_end)
  1079. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  1080. || (module_inst->ext_mem_data
  1081. && module_inst->ext_mem_data <= addr
  1082. && addr + size <= module_inst->ext_mem_data_end)
  1083. #endif
  1084. )
  1085. return true;
  1086. fail:
  1087. wasm_runtime_set_exception(module_inst, "out of bounds memory access");
  1088. return false;
  1089. }
  1090. void *
  1091. wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst,
  1092. int32 app_offset)
  1093. {
  1094. WASMMemoryInstance *memory = module_inst->default_memory;
  1095. if (0 <= app_offset && app_offset < memory->heap_base_offset)
  1096. return memory->memory_data + app_offset;
  1097. else if (memory->heap_base_offset < app_offset
  1098. && app_offset < memory->heap_base_offset
  1099. + (memory->heap_data_end - memory->heap_data))
  1100. return memory->heap_data + (app_offset - memory->heap_base_offset);
  1101. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  1102. else if (module_inst->ext_mem_data
  1103. && module_inst->ext_mem_base_offset <= app_offset
  1104. && app_offset < module_inst->ext_mem_base_offset
  1105. + module_inst->ext_mem_size)
  1106. return module_inst->ext_mem_data
  1107. + (app_offset - module_inst->ext_mem_base_offset);
  1108. #endif
  1109. else
  1110. return NULL;
  1111. }
  1112. int32
  1113. wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
  1114. void *native_ptr)
  1115. {
  1116. WASMMemoryInstance *memory = module_inst->default_memory;
  1117. if (memory->base_addr <= (uint8*)native_ptr
  1118. && (uint8*)native_ptr < memory->end_addr)
  1119. return (uint8*)native_ptr - memory->memory_data;
  1120. else if (memory->heap_data <= (uint8*)native_ptr
  1121. && (uint8*)native_ptr < memory->heap_data_end)
  1122. return memory->heap_base_offset
  1123. + ((uint8*)native_ptr - memory->heap_data);
  1124. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  1125. else if (module_inst->ext_mem_data
  1126. && module_inst->ext_mem_data <= (uint8*)native_ptr
  1127. && (uint8*)native_ptr < module_inst->ext_mem_data_end)
  1128. return module_inst->ext_mem_base_offset
  1129. + ((uint8*)native_ptr - module_inst->ext_mem_data);
  1130. #endif
  1131. else
  1132. return 0;
  1133. }
  1134. bool
  1135. wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst,
  1136. int32 app_offset,
  1137. int32 *p_app_start_offset,
  1138. int32 *p_app_end_offset)
  1139. {
  1140. int32 app_start_offset, app_end_offset;
  1141. WASMMemoryInstance *memory = module_inst->default_memory;
  1142. if (0 <= app_offset && app_offset < memory->heap_base_offset) {
  1143. app_start_offset = 0;
  1144. app_end_offset = NumBytesPerPage * memory->cur_page_count;
  1145. }
  1146. else if (memory->heap_base_offset < app_offset
  1147. && app_offset < memory->heap_base_offset
  1148. + (memory->heap_data_end - memory->heap_data)) {
  1149. app_start_offset = memory->heap_base_offset;
  1150. app_end_offset = memory->heap_base_offset
  1151. + (memory->heap_data_end - memory->heap_data);
  1152. }
  1153. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  1154. else if (module_inst->ext_mem_data
  1155. && module_inst->ext_mem_base_offset <= app_offset
  1156. && app_offset < module_inst->ext_mem_base_offset
  1157. + module_inst->ext_mem_size) {
  1158. app_start_offset = module_inst->ext_mem_base_offset;
  1159. app_end_offset = app_start_offset + module_inst->ext_mem_size;
  1160. }
  1161. #endif
  1162. else
  1163. return false;
  1164. if (p_app_start_offset)
  1165. *p_app_start_offset = app_start_offset;
  1166. if (p_app_end_offset)
  1167. *p_app_end_offset = app_end_offset;
  1168. return true;
  1169. }
  1170. bool
  1171. wasm_runtime_get_native_addr_range(WASMModuleInstance *module_inst,
  1172. uint8 *native_ptr,
  1173. uint8 **p_native_start_addr,
  1174. uint8 **p_native_end_addr)
  1175. {
  1176. uint8 *native_start_addr, *native_end_addr;
  1177. WASMMemoryInstance *memory = module_inst->default_memory;
  1178. if (memory->base_addr <= (uint8*)native_ptr
  1179. && (uint8*)native_ptr < memory->end_addr) {
  1180. native_start_addr = memory->memory_data;
  1181. native_end_addr = memory->memory_data
  1182. + NumBytesPerPage * memory->cur_page_count;
  1183. }
  1184. else if (memory->heap_data <= (uint8*)native_ptr
  1185. && (uint8*)native_ptr < memory->heap_data_end) {
  1186. native_start_addr = memory->heap_data;
  1187. native_end_addr = memory->heap_data_end;
  1188. }
  1189. #if WASM_ENABLE_EXT_MEMORY_SPACE != 0
  1190. else if (module_inst->ext_mem_data
  1191. && module_inst->ext_mem_data <= (uint8*)native_ptr
  1192. && (uint8*)native_ptr < module_inst->ext_mem_data_end) {
  1193. native_start_addr = module_inst->ext_mem_data;
  1194. native_end_addr = module_inst->ext_mem_data_end;
  1195. }
  1196. #endif
  1197. else
  1198. return false;
  1199. if (p_native_start_addr)
  1200. *p_native_start_addr = native_start_addr;
  1201. if (p_native_end_addr)
  1202. *p_native_end_addr = native_end_addr;
  1203. return true;
  1204. }
  1205. uint32
  1206. wasm_runtime_get_temp_ret(WASMModuleInstance *module_inst)
  1207. {
  1208. return module_inst->temp_ret;
  1209. }
  1210. void
  1211. wasm_runtime_set_temp_ret(WASMModuleInstance *module_inst,
  1212. uint32 temp_ret)
  1213. {
  1214. module_inst->temp_ret = temp_ret;
  1215. }
  1216. uint32
  1217. wasm_runtime_get_llvm_stack(WASMModuleInstance *module_inst)
  1218. {
  1219. return module_inst->llvm_stack;
  1220. }
  1221. void
  1222. wasm_runtime_set_llvm_stack(WASMModuleInstance *module_inst,
  1223. uint32 llvm_stack)
  1224. {
  1225. module_inst->llvm_stack = llvm_stack;
  1226. }
  1227. WASMModuleInstance*
  1228. wasm_runtime_load_aot(uint8 *aot_file, uint32 aot_file_size,
  1229. uint32 heap_size,
  1230. char *error_buf, uint32 error_buf_size)
  1231. {
  1232. (void)aot_file;
  1233. (void)aot_file_size;
  1234. (void)heap_size;
  1235. (void)error_buf;
  1236. (void)error_buf_size;
  1237. return NULL;
  1238. }
  1239. static inline void
  1240. word_copy(uint32 *dest, uint32 *src, unsigned num)
  1241. {
  1242. for (; num > 0; num--)
  1243. *dest++ = *src++;
  1244. }
  1245. #define PUT_I64_TO_ADDR(addr, value) do { \
  1246. union { int64 val; uint32 parts[2]; } u; \
  1247. u.val = (value); \
  1248. (addr)[0] = u.parts[0]; \
  1249. (addr)[1] = u.parts[1]; \
  1250. } while (0)
  1251. #define PUT_F64_TO_ADDR(addr, value) do { \
  1252. union { float64 val; uint32 parts[2]; } u; \
  1253. u.val = (value); \
  1254. (addr)[0] = u.parts[0]; \
  1255. (addr)[1] = u.parts[1]; \
  1256. } while (0)
  1257. #if !defined(__x86_64__) && !defined(__amd_64__)
  1258. typedef void (*GenericFunctionPointer)();
  1259. int64 invokeNative(uint32 *args, uint32 sz, GenericFunctionPointer f);
  1260. typedef float64 (*Float64FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  1261. typedef float32 (*Float32FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  1262. typedef int64 (*Int64FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  1263. typedef int32 (*Int32FuncPtr)(uint32*, uint32, GenericFunctionPointer);
  1264. typedef void (*VoidFuncPtr)(uint32*, uint32, GenericFunctionPointer);
  1265. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  1266. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  1267. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  1268. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  1269. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  1270. bool
  1271. wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
  1272. WASMModuleInstance *module_inst,
  1273. uint32 *argv, uint32 argc, uint32 *ret)
  1274. {
  1275. uint32 argv_buf[32], *argv1 = argv_buf, argc1, i, j = 0;
  1276. uint64 size;
  1277. #if !defined(__arm__) && !defined(__mips__)
  1278. argc1 = argc + 2;
  1279. #else
  1280. argc1 = func_type->param_count * 2 + 2;
  1281. #endif
  1282. if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
  1283. size = ((uint64)sizeof(uint32)) * argc1;
  1284. if (size >= UINT_MAX
  1285. || !(argv1 = wasm_malloc((uint32)size))) {
  1286. wasm_runtime_set_exception(module_inst, "allocate memory failed.");
  1287. return false;
  1288. }
  1289. }
  1290. for (i = 0; i < sizeof(WASMModuleInstance*) / sizeof(uint32); i++)
  1291. argv1[j++] = ((uint32*)&module_inst)[i];
  1292. #if !defined(__arm__) && !defined(__mips__)
  1293. word_copy(argv1 + j, argv, argc);
  1294. j += argc;
  1295. #else
  1296. for (i = 0; i < func_type->param_count; i++) {
  1297. switch (func_type->types[i]) {
  1298. case VALUE_TYPE_I32:
  1299. argv1[j++] = *argv++;
  1300. break;
  1301. case VALUE_TYPE_I64:
  1302. case VALUE_TYPE_F64:
  1303. /* 64-bit data must be 8 bytes alined in arm and mips */
  1304. if (j & 1)
  1305. j++;
  1306. argv1[j++] = *argv++;
  1307. argv1[j++] = *argv++;
  1308. break;
  1309. case VALUE_TYPE_F32:
  1310. argv1[j++] = *argv++;
  1311. break;
  1312. default:
  1313. wasm_assert(0);
  1314. break;
  1315. }
  1316. }
  1317. #endif
  1318. argc1 = j;
  1319. if (func_type->result_count == 0) {
  1320. invokeNative_Void(argv1, argc1, func_ptr);
  1321. }
  1322. else {
  1323. switch (func_type->types[func_type->param_count]) {
  1324. case VALUE_TYPE_I32:
  1325. ret[0] = invokeNative_Int32(argv1, argc1, func_ptr);
  1326. break;
  1327. case VALUE_TYPE_I64:
  1328. PUT_I64_TO_ADDR(ret, invokeNative_Int64(argv1, argc1, func_ptr));
  1329. break;
  1330. case VALUE_TYPE_F32:
  1331. *(float32*)ret = invokeNative_Float32(argv1, argc1, func_ptr);
  1332. break;
  1333. case VALUE_TYPE_F64:
  1334. PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, argc1, func_ptr));
  1335. break;
  1336. default:
  1337. wasm_assert(0);
  1338. break;
  1339. }
  1340. }
  1341. if (argv1 != argv_buf)
  1342. wasm_free(argv1);
  1343. return true;
  1344. }
  1345. #else /* else of !defined(__x86_64__) && !defined(__amd_64__) */
  1346. typedef void (*GenericFunctionPointer)();
  1347. int64 invokeNative(uint64 *args, uint64 n_fps, uint64 n_stacks, GenericFunctionPointer f);
  1348. typedef float64 (*Float64FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer);
  1349. typedef float32 (*Float32FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer);
  1350. typedef int64 (*Int64FuncPtr)(uint64*,uint64, uint64, GenericFunctionPointer);
  1351. typedef int32 (*Int32FuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer);
  1352. typedef void (*VoidFuncPtr)(uint64*, uint64, uint64, GenericFunctionPointer);
  1353. static Float64FuncPtr invokeNative_Float64 = (Float64FuncPtr)invokeNative;
  1354. static Float32FuncPtr invokeNative_Float32 = (Float32FuncPtr)invokeNative;
  1355. static Int64FuncPtr invokeNative_Int64 = (Int64FuncPtr)invokeNative;
  1356. static Int32FuncPtr invokeNative_Int32 = (Int32FuncPtr)invokeNative;
  1357. static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
  1358. #if defined(_WIN32) || defined(_WIN32_)
  1359. #define MAX_REG_FLOATS 4
  1360. #define MAX_REG_INTS 4
  1361. #else
  1362. #define MAX_REG_FLOATS 8
  1363. #define MAX_REG_INTS 6
  1364. #endif
  1365. bool
  1366. wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
  1367. WASMModuleInstance *module_inst,
  1368. uint32 *argv, uint32 argc, uint32 *ret)
  1369. {
  1370. uint64 argv_buf[32], *argv1 = argv_buf, *fps, *ints, *stacks, size;
  1371. uint32 *argv_src = argv, i, argc1, n_ints = 0, n_stacks = 0;
  1372. #if defined(_WIN32) || defined(_WIN32_)
  1373. /* important difference in calling conventions */
  1374. #define n_fps n_ints
  1375. #else
  1376. int n_fps = 0;
  1377. #endif
  1378. argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2;
  1379. if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
  1380. size = sizeof(uint64) * argc1;
  1381. if (size >= UINT32_MAX
  1382. || !(argv1 = wasm_malloc(size))) {
  1383. wasm_runtime_set_exception(module_inst, "allocate memory failed.");
  1384. return false;
  1385. }
  1386. }
  1387. fps = argv1 + 1;
  1388. ints = fps + MAX_REG_FLOATS;
  1389. stacks = ints + MAX_REG_INTS;
  1390. ints[n_ints++] = (uint64)(uintptr_t)module_inst;
  1391. for (i = 0; i < func_type->param_count; i++) {
  1392. switch (func_type->types[i]) {
  1393. case VALUE_TYPE_I32:
  1394. if (n_ints < MAX_REG_INTS)
  1395. ints[n_ints++] = *argv_src++;
  1396. else
  1397. stacks[n_stacks++] = *argv_src++;
  1398. break;
  1399. case VALUE_TYPE_I64:
  1400. if (n_ints < MAX_REG_INTS)
  1401. ints[n_ints++] = *(uint64*)argv_src;
  1402. else
  1403. stacks[n_stacks++] = *(uint64*)argv_src;
  1404. argv_src += 2;
  1405. break;
  1406. case VALUE_TYPE_F32:
  1407. if (n_fps < MAX_REG_FLOATS)
  1408. *(float64*)&fps[n_fps++] = *(float32*)argv_src++;
  1409. else
  1410. *(float64*)&stacks[n_stacks++] = *(float32*)argv_src++;
  1411. break;
  1412. case VALUE_TYPE_F64:
  1413. if (n_fps < MAX_REG_FLOATS)
  1414. *(float64*)&fps[n_fps++] = *(float64*)argv_src;
  1415. else
  1416. *(float64*)&stacks[n_stacks++] = *(float64*)argv_src;
  1417. argv_src += 2;
  1418. break;
  1419. default:
  1420. wasm_assert(0);
  1421. break;
  1422. }
  1423. }
  1424. if (func_type->result_count == 0) {
  1425. invokeNative_Void(argv1, n_fps, n_stacks, func_ptr);
  1426. }
  1427. else {
  1428. switch (func_type->types[func_type->param_count]) {
  1429. case VALUE_TYPE_I32:
  1430. ret[0] = invokeNative_Int32(argv1, n_fps, n_stacks, func_ptr);
  1431. break;
  1432. case VALUE_TYPE_I64:
  1433. PUT_I64_TO_ADDR(ret, invokeNative_Int64(argv1, n_fps, n_stacks, func_ptr));
  1434. break;
  1435. case VALUE_TYPE_F32:
  1436. *(float32*)ret = invokeNative_Float32(argv1, n_fps, n_stacks, func_ptr);
  1437. break;
  1438. case VALUE_TYPE_F64:
  1439. PUT_F64_TO_ADDR(ret, invokeNative_Float64(argv1, n_fps, n_stacks, func_ptr));
  1440. break;
  1441. default:
  1442. wasm_assert(0);
  1443. break;
  1444. }
  1445. }
  1446. if (argv1 != argv_buf)
  1447. wasm_free(argv1);
  1448. return true;
  1449. }
  1450. #endif /* end of !defined(__x86_64__) && !defined(__amd_64__) */