gc_object.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "gc_object.h"
  6. #include "mem_alloc.h"
  7. #include "../wasm_runtime_common.h"
  8. #if WASM_ENABLE_INTERP != 0
  9. #include "../interpreter/wasm_runtime.h"
  10. #endif
  11. #if WASM_ENABLE_AOT != 0
  12. #include "../aot/aot_runtime.h"
  13. #endif
  14. #if WASM_ENABLE_STRINGREF != 0
  15. #include "string_object.h"
  16. #endif
  17. WASMRttTypeRef
  18. wasm_rtt_type_new(WASMType *defined_type, uint32 defined_type_idx,
  19. WASMRttType **rtt_types, uint32 rtt_type_count,
  20. korp_mutex *rtt_type_lock)
  21. {
  22. WASMRttType *rtt_type;
  23. bh_assert(defined_type_idx < rtt_type_count);
  24. os_mutex_lock(rtt_type_lock);
  25. if (rtt_types[defined_type_idx]) {
  26. os_mutex_unlock(rtt_type_lock);
  27. return rtt_types[defined_type_idx];
  28. }
  29. if ((rtt_type = wasm_runtime_malloc(sizeof(WASMRttType)))) {
  30. rtt_type->type_flag = defined_type->type_flag;
  31. rtt_type->inherit_depth = defined_type->inherit_depth;
  32. rtt_type->defined_type = defined_type;
  33. rtt_type->root_type = defined_type->root_type;
  34. rtt_types[defined_type_idx] = rtt_type;
  35. }
  36. os_mutex_unlock(rtt_type_lock);
  37. return rtt_type;
  38. }
  39. static void *
  40. gc_obj_malloc(void *heap_handle, uint64 size)
  41. {
  42. void *mem;
  43. if (size >= UINT32_MAX
  44. || !(mem = mem_allocator_malloc_with_gc(heap_handle, (uint32)size))) {
  45. LOG_WARNING("warning: failed to allocate memory for gc object");
  46. return NULL;
  47. }
  48. memset(mem, 0, (uint32)size);
  49. return mem;
  50. }
  51. static void *
  52. get_gc_heap_handle(WASMExecEnv *exec_env)
  53. {
  54. void *gc_heap_handle = NULL;
  55. WASMModuleInstanceCommon *module_inst = exec_env->module_inst;
  56. #if WASM_ENABLE_INTERP != 0
  57. if (module_inst->module_type == Wasm_Module_Bytecode)
  58. gc_heap_handle =
  59. ((WASMModuleInstance *)module_inst)->e->common.gc_heap_handle;
  60. #endif
  61. #if WASM_ENABLE_AOT != 0
  62. if (module_inst->module_type == Wasm_Module_AoT)
  63. gc_heap_handle =
  64. ((AOTModuleInstanceExtra *)((AOTModuleInstance *)module_inst)->e)
  65. ->common.gc_heap_handle;
  66. #endif
  67. bh_assert(gc_heap_handle);
  68. return gc_heap_handle;
  69. }
  70. WASMStructObjectRef
  71. wasm_struct_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type)
  72. {
  73. WASMStructObjectRef struct_obj;
  74. WASMStructType *struct_type;
  75. bh_assert(rtt_type->type_flag == WASM_TYPE_STRUCT);
  76. struct_type = (WASMStructType *)rtt_type->defined_type;
  77. if (!(struct_obj = gc_obj_malloc(heap_handle, struct_type->total_size))) {
  78. return NULL;
  79. }
  80. struct_obj->header = (WASMObjectHeader)rtt_type;
  81. return struct_obj;
  82. }
  83. WASMStructObjectRef
  84. wasm_struct_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type)
  85. {
  86. void *heap_handle = get_gc_heap_handle(exec_env);
  87. return wasm_struct_obj_new_internal(heap_handle, rtt_type);
  88. }
  89. void
  90. wasm_struct_obj_set_field(WASMStructObjectRef struct_obj, uint32 field_idx,
  91. const WASMValue *value)
  92. {
  93. WASMRttTypeRef rtt_type =
  94. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
  95. WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
  96. WASMStructFieldType *field;
  97. uint8 field_size, *field_data;
  98. bh_assert(field_idx < struct_type->field_count);
  99. field = struct_type->fields + field_idx;
  100. field_data = (uint8 *)struct_obj + field->field_offset;
  101. field_size = field->field_size;
  102. if (field_size == 4) {
  103. *(int32 *)field_data = value->i32;
  104. }
  105. else if (field_size == 8) {
  106. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  107. || defined(BUILD_TARGET_X86_32)
  108. *(int64 *)field_data = value->i64;
  109. #else
  110. PUT_I64_TO_ADDR((uint32 *)field_data, value->i64);
  111. #endif
  112. }
  113. else if (field_size == 1) {
  114. *(int8 *)field_data = (int8)value->i32;
  115. }
  116. else if (field_size == 2) {
  117. *(int16 *)field_data = (int16)value->i32;
  118. }
  119. else {
  120. bh_assert(0);
  121. }
  122. }
  123. void
  124. wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj,
  125. uint32 field_idx, bool sign_extend, WASMValue *value)
  126. {
  127. WASMRttTypeRef rtt_type =
  128. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
  129. WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
  130. WASMStructFieldType *field;
  131. uint8 *field_data, field_size;
  132. bh_assert(field_idx < struct_type->field_count);
  133. field = struct_type->fields + field_idx;
  134. field_data = (uint8 *)struct_obj + field->field_offset;
  135. field_size = field->field_size;
  136. if (field_size == 4) {
  137. value->i32 = *(int32 *)field_data;
  138. }
  139. else if (field_size == 8) {
  140. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  141. || defined(BUILD_TARGET_X86_32)
  142. value->i64 = *(int64 *)field_data;
  143. #else
  144. value->i64 = GET_I64_FROM_ADDR((uint32 *)field_data);
  145. #endif
  146. }
  147. else if (field_size == 1) {
  148. if (sign_extend)
  149. value->i32 = (int32)(*(int8 *)field_data);
  150. else
  151. value->u32 = (uint32)(*(uint8 *)field_data);
  152. }
  153. else if (field_size == 2) {
  154. if (sign_extend)
  155. value->i32 = (int32)(*(int16 *)field_data);
  156. else
  157. value->u32 = (uint32)(*(uint16 *)field_data);
  158. }
  159. else {
  160. bh_assert(0);
  161. }
  162. }
  163. uint32
  164. wasm_struct_obj_get_field_count(const WASMStructObjectRef struct_obj)
  165. {
  166. WASMRttTypeRef rtt_type =
  167. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
  168. WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
  169. return struct_type->field_count;
  170. }
  171. WASMArrayObjectRef
  172. wasm_array_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
  173. uint32 length, WASMValue *init_value)
  174. {
  175. WASMArrayObjectRef array_obj;
  176. WASMArrayType *array_type;
  177. uint64 total_size;
  178. uint32 elem_size, elem_size_log, i;
  179. bh_assert(rtt_type->type_flag == WASM_TYPE_ARRAY);
  180. if (length >= (1 << 29))
  181. return NULL;
  182. array_type = (WASMArrayType *)rtt_type->defined_type;
  183. if (array_type->elem_type == PACKED_TYPE_I8) {
  184. elem_size = 1;
  185. elem_size_log = 0;
  186. }
  187. else if (array_type->elem_type == PACKED_TYPE_I16) {
  188. elem_size = 2;
  189. elem_size_log = 1;
  190. }
  191. else {
  192. elem_size = wasm_value_type_size(array_type->elem_type);
  193. elem_size_log = (elem_size == 4) ? 2 : 3;
  194. }
  195. total_size =
  196. offsetof(WASMArrayObject, elem_data) + (uint64)elem_size * length;
  197. if (!(array_obj = gc_obj_malloc(heap_handle, total_size))) {
  198. return NULL;
  199. }
  200. array_obj->header = (WASMObjectHeader)rtt_type;
  201. array_obj->length = (length << 2) | elem_size_log;
  202. if (init_value != NULL) {
  203. for (i = 0; i < length; i++) {
  204. if (wasm_is_type_reftype(array_type->elem_type)) {
  205. uint32 *elem_addr =
  206. (uint32 *)array_obj->elem_data + REF_CELL_NUM * i;
  207. PUT_REF_TO_ADDR(elem_addr, init_value->gc_obj);
  208. }
  209. else if (array_type->elem_type == VALUE_TYPE_I32
  210. || array_type->elem_type == VALUE_TYPE_F32) {
  211. ((int32 *)array_obj->elem_data)[i] = init_value->i32;
  212. }
  213. else if (array_type->elem_type == PACKED_TYPE_I8) {
  214. ((int8 *)array_obj->elem_data)[i] = (int8)init_value->i32;
  215. }
  216. else if (array_type->elem_type == PACKED_TYPE_I16) {
  217. ((int16 *)array_obj->elem_data)[i] = (int16)init_value->i32;
  218. }
  219. else {
  220. uint32 *elem_addr = (uint32 *)array_obj->elem_data + 2 * i;
  221. PUT_I64_TO_ADDR(elem_addr, init_value->i64);
  222. }
  223. }
  224. }
  225. return array_obj;
  226. }
  227. WASMArrayObjectRef
  228. wasm_array_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
  229. uint32 length, WASMValue *init_value)
  230. {
  231. void *heap_handle = get_gc_heap_handle(exec_env);
  232. return wasm_array_obj_new_internal(heap_handle, rtt_type, length,
  233. init_value);
  234. }
  235. void
  236. wasm_array_obj_set_elem(WASMArrayObjectRef array_obj, uint32 elem_idx,
  237. const WASMValue *value)
  238. {
  239. uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
  240. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
  241. switch (elem_size) {
  242. case 1:
  243. *(int8 *)elem_data = (int8)value->i32;
  244. break;
  245. case 2:
  246. *(int16 *)elem_data = (int16)value->i32;
  247. break;
  248. case 4:
  249. *(int32 *)elem_data = value->i32;
  250. break;
  251. case 8:
  252. PUT_I64_TO_ADDR((uint32 *)elem_data, value->i64);
  253. break;
  254. }
  255. }
  256. void
  257. wasm_array_obj_get_elem(const WASMArrayObjectRef array_obj, uint32 elem_idx,
  258. bool sign_extend, WASMValue *value)
  259. {
  260. uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
  261. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
  262. switch (elem_size) {
  263. case 1:
  264. value->i32 = sign_extend ? (int32)(*(int8 *)elem_data)
  265. : (int32)(uint32)(*(uint8 *)elem_data);
  266. break;
  267. case 2:
  268. value->i32 = sign_extend ? (int32)(*(int16 *)elem_data)
  269. : (int32)(uint32)(*(uint16 *)elem_data);
  270. break;
  271. case 4:
  272. value->i32 = *(int32 *)elem_data;
  273. break;
  274. case 8:
  275. value->i64 = GET_I64_FROM_ADDR((uint32 *)elem_data);
  276. break;
  277. }
  278. }
  279. void
  280. wasm_array_obj_fill(const WASMArrayObjectRef array_obj, uint32 elem_idx,
  281. uint32 len, WASMValue *value)
  282. {
  283. uint32 i;
  284. uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
  285. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
  286. if (elem_size == 1) {
  287. memset(elem_data, (int8)value->i32, len);
  288. return;
  289. }
  290. for (i = 0; i < len; i++) {
  291. switch (elem_size) {
  292. case 2:
  293. *(int16 *)elem_data = (int16)value->i32;
  294. break;
  295. case 4:
  296. *(int32 *)elem_data = value->i32;
  297. break;
  298. case 8:
  299. PUT_I64_TO_ADDR((uint32 *)elem_data, value->i64);
  300. break;
  301. }
  302. elem_data += elem_size;
  303. }
  304. }
  305. void
  306. wasm_array_obj_copy(WASMArrayObjectRef dst_obj, uint32 dst_idx,
  307. WASMArrayObjectRef src_obj, uint32 src_idx, uint32 len)
  308. {
  309. uint8 *dst_data = wasm_array_obj_elem_addr(dst_obj, dst_idx);
  310. uint8 *src_data = wasm_array_obj_elem_addr(src_obj, src_idx);
  311. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(dst_obj);
  312. bh_memmove_s(dst_data, elem_size * len, src_data, elem_size * len);
  313. }
  314. uint32
  315. wasm_array_obj_length(const WASMArrayObjectRef array_obj)
  316. {
  317. return array_obj->length >> WASM_ARRAY_LENGTH_SHIFT;
  318. }
  319. void *
  320. wasm_array_obj_first_elem_addr(const WASMArrayObjectRef array_obj)
  321. {
  322. return array_obj->elem_data;
  323. }
  324. void *
  325. wasm_array_obj_elem_addr(const WASMArrayObjectRef array_obj, uint32 elem_idx)
  326. {
  327. return array_obj->elem_data
  328. + (elem_idx << wasm_array_obj_elem_size_log(array_obj));
  329. }
  330. WASMFuncObjectRef
  331. wasm_func_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
  332. uint32 func_idx_bound)
  333. {
  334. WASMFuncObjectRef func_obj;
  335. uint64 total_size;
  336. bh_assert(rtt_type->type_flag == WASM_TYPE_FUNC);
  337. total_size = sizeof(WASMFuncObject);
  338. if (!(func_obj = gc_obj_malloc(heap_handle, total_size))) {
  339. return NULL;
  340. }
  341. func_obj->header = (WASMObjectHeader)rtt_type;
  342. func_obj->func_idx_bound = func_idx_bound;
  343. return func_obj;
  344. }
  345. WASMFuncObjectRef
  346. wasm_func_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
  347. uint32 func_idx_bound)
  348. {
  349. void *heap_handle = get_gc_heap_handle(exec_env);
  350. return wasm_func_obj_new_internal(heap_handle, rtt_type, func_idx_bound);
  351. }
  352. uint32
  353. wasm_func_obj_get_func_idx_bound(const WASMFuncObjectRef func_obj)
  354. {
  355. return func_obj->func_idx_bound;
  356. }
  357. WASMFuncType *
  358. wasm_func_obj_get_func_type(const WASMFuncObjectRef func_obj)
  359. {
  360. WASMRttTypeRef rtt_type =
  361. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)func_obj);
  362. bh_assert(rtt_type->type_flag == WASM_TYPE_FUNC);
  363. return (WASMFuncType *)rtt_type->defined_type;
  364. }
  365. WASMExternrefObjectRef
  366. wasm_externref_obj_new(WASMExecEnv *exec_env, const void *host_obj)
  367. {
  368. void *heap_handle = get_gc_heap_handle(exec_env);
  369. WASMAnyrefObjectRef anyref_obj;
  370. WASMExternrefObjectRef externref_obj;
  371. WASMLocalObjectRef local_ref;
  372. if (!(anyref_obj = gc_obj_malloc(heap_handle, sizeof(WASMAnyrefObject)))) {
  373. return NULL;
  374. }
  375. anyref_obj->header = WASM_OBJ_ANYREF_OBJ_FLAG;
  376. anyref_obj->host_obj = host_obj;
  377. /* Lock anyref_obj in case it is reclaimed when allocating memory below */
  378. wasm_runtime_push_local_obj_ref(exec_env, &local_ref);
  379. local_ref.val = (WASMObjectRef)anyref_obj;
  380. if (!(externref_obj =
  381. gc_obj_malloc(heap_handle, sizeof(WASMExternrefObject)))) {
  382. wasm_runtime_pop_local_obj_ref(exec_env);
  383. return NULL;
  384. }
  385. externref_obj->header = WASM_OBJ_EXTERNREF_OBJ_FLAG;
  386. externref_obj->internal_obj = (WASMObjectRef)anyref_obj;
  387. wasm_runtime_pop_local_obj_ref(exec_env);
  388. return externref_obj;
  389. }
  390. WASMAnyrefObjectRef
  391. wasm_anyref_obj_new(WASMExecEnv *exec_env, const void *host_obj)
  392. {
  393. void *heap_handle = get_gc_heap_handle(exec_env);
  394. WASMAnyrefObjectRef anyref_obj;
  395. if (!(anyref_obj = gc_obj_malloc(heap_handle, sizeof(WASMAnyrefObject)))) {
  396. return NULL;
  397. }
  398. anyref_obj->header = WASM_OBJ_ANYREF_OBJ_FLAG;
  399. anyref_obj->host_obj = host_obj;
  400. return anyref_obj;
  401. }
  402. WASMObjectRef
  403. wasm_externref_obj_to_internal_obj(WASMExternrefObjectRef externref_obj)
  404. {
  405. return externref_obj->internal_obj;
  406. }
  407. WASMExternrefObjectRef
  408. wasm_internal_obj_to_externref_obj(WASMExecEnv *exec_env,
  409. WASMObjectRef internal_obj)
  410. {
  411. void *heap_handle = get_gc_heap_handle(exec_env);
  412. WASMExternrefObjectRef externref_obj;
  413. if (!(externref_obj =
  414. gc_obj_malloc(heap_handle, sizeof(WASMExternrefObject)))) {
  415. return NULL;
  416. }
  417. externref_obj->header = WASM_OBJ_EXTERNREF_OBJ_FLAG;
  418. externref_obj->internal_obj = internal_obj;
  419. return externref_obj;
  420. }
  421. const void *
  422. wasm_anyref_obj_get_value(WASMAnyrefObjectRef anyref_obj)
  423. {
  424. return anyref_obj->host_obj;
  425. }
  426. const void *
  427. wasm_externref_obj_get_value(const WASMExternrefObjectRef externref_obj)
  428. {
  429. if (wasm_obj_is_anyref_obj(externref_obj->internal_obj))
  430. return ((WASMAnyrefObjectRef)externref_obj->internal_obj)->host_obj;
  431. else
  432. return externref_obj->internal_obj;
  433. }
  434. WASMI31ObjectRef
  435. wasm_i31_obj_new(uint32 i31_value)
  436. {
  437. return (WASMI31ObjectRef)((i31_value << 1) | 1);
  438. }
  439. uint32
  440. wasm_i31_obj_get_value(WASMI31ObjectRef i31_obj, bool sign_extend)
  441. {
  442. uint32 i31_value = (uint32)(((uintptr_t)i31_obj) >> 1);
  443. if (sign_extend && (i31_value & 0x40000000)) /* bit 30 is 1 */
  444. /* set bit 31 to 1 */
  445. i31_value |= 0x80000000;
  446. return i31_value;
  447. }
  448. bool
  449. wasm_obj_is_i31_obj(WASMObjectRef obj)
  450. {
  451. bh_assert(obj);
  452. return (((uintptr_t)obj) & 1) ? true : false;
  453. }
  454. bool
  455. wasm_obj_is_externref_obj(WASMObjectRef obj)
  456. {
  457. bh_assert(obj);
  458. return (!wasm_obj_is_i31_obj(obj)
  459. && (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG))
  460. ? true
  461. : false;
  462. }
  463. bool
  464. wasm_obj_is_anyref_obj(WASMObjectRef obj)
  465. {
  466. bh_assert(obj);
  467. return (!wasm_obj_is_i31_obj(obj)
  468. && (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG))
  469. ? true
  470. : false;
  471. }
  472. bool
  473. wasm_obj_is_i31_externref_or_anyref_obj(WASMObjectRef obj)
  474. {
  475. bh_assert(obj);
  476. return (wasm_obj_is_i31_obj(obj)
  477. || (obj->header
  478. & (WASM_OBJ_EXTERNREF_OBJ_FLAG | WASM_OBJ_ANYREF_OBJ_FLAG)))
  479. ? true
  480. : false;
  481. }
  482. bool
  483. wasm_obj_is_struct_obj(WASMObjectRef obj)
  484. {
  485. WASMRttTypeRef rtt_type;
  486. bh_assert(obj);
  487. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  488. return false;
  489. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  490. return rtt_type->type_flag == WASM_TYPE_STRUCT ? true : false;
  491. }
  492. bool
  493. wasm_obj_is_array_obj(WASMObjectRef obj)
  494. {
  495. WASMRttTypeRef rtt_type;
  496. bh_assert(obj);
  497. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  498. return false;
  499. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  500. return rtt_type->type_flag == WASM_TYPE_ARRAY ? true : false;
  501. }
  502. bool
  503. wasm_obj_is_func_obj(WASMObjectRef obj)
  504. {
  505. WASMRttTypeRef rtt_type;
  506. bh_assert(obj);
  507. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  508. return false;
  509. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  510. return rtt_type->type_flag == WASM_TYPE_FUNC ? true : false;
  511. }
  512. bool
  513. wasm_obj_is_internal_obj(WASMObjectRef obj)
  514. {
  515. WASMRttTypeRef rtt_type;
  516. bh_assert(obj);
  517. if (wasm_obj_is_i31_obj(obj))
  518. return true;
  519. else if (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG)
  520. return true;
  521. else if (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG)
  522. return false;
  523. else {
  524. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  525. return (rtt_type->type_flag == WASM_TYPE_STRUCT
  526. || rtt_type->type_flag == WASM_TYPE_ARRAY)
  527. ? true
  528. : false;
  529. }
  530. }
  531. bool
  532. wasm_obj_is_eq_obj(WASMObjectRef obj)
  533. {
  534. WASMRttTypeRef rtt_type;
  535. bh_assert(obj);
  536. if (wasm_obj_is_i31_obj(obj))
  537. return true;
  538. else if ((obj->header & WASM_OBJ_ANYREF_OBJ_FLAG)
  539. || (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG))
  540. return false;
  541. else {
  542. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  543. return (rtt_type->type_flag == WASM_TYPE_STRUCT
  544. || rtt_type->type_flag == WASM_TYPE_ARRAY)
  545. ? true
  546. : false;
  547. }
  548. }
  549. bool
  550. wasm_obj_is_instance_of(WASMObjectRef obj, uint32 type_idx, WASMType **types,
  551. uint32 type_count)
  552. {
  553. WASMRttTypeRef rtt_type_sub;
  554. WASMType *type_sub, *type_parent;
  555. uint32 distance, i;
  556. bh_assert(obj);
  557. bh_assert(type_idx < type_count);
  558. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  559. return false;
  560. rtt_type_sub = (WASMRttTypeRef)wasm_object_header(obj);
  561. type_parent = types[type_idx];
  562. if (!(rtt_type_sub->root_type == type_parent->root_type
  563. && rtt_type_sub->inherit_depth >= type_parent->inherit_depth))
  564. return false;
  565. type_sub = rtt_type_sub->defined_type;
  566. distance = type_sub->inherit_depth - type_parent->inherit_depth;
  567. for (i = 0; i < distance; i++) {
  568. type_sub = type_sub->parent_type;
  569. }
  570. return (type_sub == type_parent) ? true : false;
  571. }
  572. bool
  573. wasm_obj_is_type_of(WASMObjectRef obj, int32 heap_type)
  574. {
  575. bh_assert(obj);
  576. switch (heap_type) {
  577. case HEAP_TYPE_FUNC:
  578. return wasm_obj_is_func_obj(obj);
  579. case HEAP_TYPE_EXTERN:
  580. return wasm_obj_is_externref_obj(obj);
  581. case HEAP_TYPE_ANY:
  582. return wasm_obj_is_internal_obj(obj);
  583. case HEAP_TYPE_EQ:
  584. return wasm_obj_is_eq_obj(obj);
  585. case HEAP_TYPE_I31:
  586. return wasm_obj_is_i31_obj(obj);
  587. case HEAP_TYPE_STRUCT:
  588. return wasm_obj_is_struct_obj(obj);
  589. case HEAP_TYPE_ARRAY:
  590. return wasm_obj_is_array_obj(obj);
  591. #if WASM_ENABLE_STRINGREF != 0
  592. case HEAP_TYPE_STRINGREF:
  593. return wasm_obj_is_stringref_obj(obj);
  594. case HEAP_TYPE_STRINGVIEWWTF8:
  595. return wasm_obj_is_stringview_wtf8_obj(obj);
  596. case HEAP_TYPE_STRINGVIEWWTF16:
  597. return wasm_obj_is_stringview_wtf16_obj(obj);
  598. #endif
  599. case HEAP_TYPE_NONE:
  600. case HEAP_TYPE_NOFUNC:
  601. case HEAP_TYPE_NOEXTERN:
  602. return false;
  603. default:
  604. bh_assert(0);
  605. break;
  606. }
  607. return false;
  608. }
  609. bool
  610. wasm_obj_equal(WASMObjectRef obj1, WASMObjectRef obj2)
  611. {
  612. /* TODO: do we need to compare the internal details of the objects */
  613. return obj1 == obj2 ? true : false;
  614. }
  615. bool
  616. wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
  617. uint32 *p_ref_num, uint16 **p_ref_list,
  618. uint32 *p_ref_start_offset)
  619. {
  620. WASMRttTypeRef rtt_type;
  621. bh_assert(wasm_obj_is_created_from_heap(obj));
  622. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  623. if (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG) {
  624. /* externref object */
  625. static uint16 externref_obj_ref_list[] = { (uint16)offsetof(
  626. WASMExternrefObject, internal_obj) };
  627. *p_is_compact_mode = false;
  628. *p_ref_num = 1;
  629. *p_ref_list = externref_obj_ref_list;
  630. return true;
  631. }
  632. else if (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG) {
  633. /* anyref object */
  634. *p_is_compact_mode = false;
  635. *p_ref_num = 0;
  636. *p_ref_list = NULL;
  637. return true;
  638. }
  639. #if WASM_ENABLE_STRINGREF != 0
  640. else if (rtt_type->type_flag == WASM_TYPE_STRINGREF
  641. || rtt_type->type_flag == WASM_TYPE_STRINGVIEWWTF8
  642. || rtt_type->type_flag == WASM_TYPE_STRINGVIEWWTF16
  643. || rtt_type->type_flag == WASM_TYPE_STRINGVIEWITER) {
  644. /* stringref/stringview_wtf8/stringview_wtf16/stringview_iter object */
  645. *p_is_compact_mode = false;
  646. *p_ref_num = 0;
  647. *p_ref_list = NULL;
  648. return true;
  649. }
  650. #endif /* end of WASM_ENABLE_STRINGREF != 0 */
  651. else if (rtt_type->defined_type->type_flag == WASM_TYPE_FUNC) {
  652. /* function object */
  653. *p_is_compact_mode = false;
  654. *p_ref_num = 0;
  655. *p_ref_list = NULL;
  656. return true;
  657. }
  658. else if (rtt_type->defined_type->type_flag == WASM_TYPE_STRUCT) {
  659. /* struct object */
  660. WASMStructType *type = (WASMStructType *)rtt_type->defined_type;
  661. *p_is_compact_mode = false;
  662. *p_ref_num = *type->reference_table;
  663. *p_ref_list = type->reference_table + 1;
  664. return true;
  665. }
  666. else if (rtt_type->defined_type->type_flag == WASM_TYPE_ARRAY) {
  667. /* array object */
  668. WASMArrayType *type = (WASMArrayType *)rtt_type->defined_type;
  669. if (wasm_is_type_reftype(type->elem_type)) {
  670. *p_is_compact_mode = true;
  671. *p_ref_num = wasm_array_obj_length((WASMArrayObjectRef)obj);
  672. *p_ref_start_offset = (uint16)offsetof(WASMArrayObject, elem_data);
  673. }
  674. else {
  675. *p_is_compact_mode = false;
  676. *p_ref_num = 0;
  677. *p_ref_list = NULL;
  678. }
  679. return true;
  680. }
  681. else {
  682. bh_assert(0);
  683. return false;
  684. }
  685. }
  686. bool
  687. wasm_obj_set_gc_finalizer(wasm_exec_env_t exec_env, const wasm_obj_t obj,
  688. wasm_obj_finalizer_t cb, void *data)
  689. {
  690. void *heap_handle = get_gc_heap_handle(exec_env);
  691. return mem_allocator_set_gc_finalizer(heap_handle, obj, (gc_finalizer_t)cb,
  692. data);
  693. }
  694. void
  695. wasm_obj_unset_gc_finalizer(wasm_exec_env_t exec_env, void *obj)
  696. {
  697. void *heap_handle = get_gc_heap_handle(exec_env);
  698. mem_allocator_unset_gc_finalizer(heap_handle, obj);
  699. }
  700. #if WASM_ENABLE_STRINGREF != 0
  701. WASMRttTypeRef
  702. wasm_stringref_rtt_type_new(uint16 type_flag, WASMRttType **rtt_types,
  703. korp_mutex *rtt_type_lock)
  704. {
  705. WASMRttType *rtt_type;
  706. uint32 index;
  707. bh_assert(type_flag >= WASM_TYPE_STRINGREF
  708. && type_flag <= WASM_TYPE_STRINGVIEWITER);
  709. index = type_flag - WASM_TYPE_STRINGREF;
  710. os_mutex_lock(rtt_type_lock);
  711. if (rtt_types[index]) {
  712. os_mutex_unlock(rtt_type_lock);
  713. return rtt_types[index];
  714. }
  715. if ((rtt_type = wasm_runtime_malloc(sizeof(WASMRttType)))) {
  716. memset(rtt_type, 0, sizeof(WASMRttType));
  717. rtt_type->type_flag = type_flag;
  718. rtt_types[index] = rtt_type;
  719. }
  720. os_mutex_unlock(rtt_type_lock);
  721. return rtt_type;
  722. }
  723. static void
  724. wasm_stringref_obj_finalizer(WASMStringrefObjectRef stringref_obj, void *data)
  725. {
  726. wasm_string_destroy(
  727. (WASMString)wasm_stringref_obj_get_value(stringref_obj));
  728. }
  729. static void
  730. wasm_stringview_wtf8_obj_finalizer(WASMStringviewWTF8ObjectRef stringref_obj,
  731. void *data)
  732. {
  733. wasm_string_destroy(
  734. (WASMString)wasm_stringview_wtf8_obj_get_value(stringref_obj));
  735. }
  736. static void
  737. wasm_stringview_wtf16_obj_finalizer(WASMStringviewWTF16ObjectRef stringref_obj,
  738. void *data)
  739. {
  740. wasm_string_destroy(
  741. (WASMString)wasm_stringview_wtf16_obj_get_value(stringref_obj));
  742. }
  743. static void
  744. wasm_stringview_iter_obj_finalizer(WASMStringviewIterObjectRef stringref_obj,
  745. void *data)
  746. {
  747. wasm_string_destroy(
  748. (WASMString)wasm_stringview_iter_obj_get_value(stringref_obj));
  749. }
  750. static WASMObjectRef
  751. stringref_obj_new(WASMExecEnv *exec_env, uint32 type, const void *str_obj,
  752. int32 pos)
  753. {
  754. WASMObjectRef stringref_obj = NULL;
  755. void *heap_handle = get_gc_heap_handle(exec_env);
  756. WASMModuleInstanceCommon *module_inst =
  757. wasm_runtime_get_module_inst(exec_env);
  758. WASMRttTypeRef rtt_type = NULL;
  759. #if WASM_ENABLE_INTERP != 0
  760. if (module_inst->module_type == Wasm_Module_Bytecode) {
  761. WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
  762. rtt_type = wasm_stringref_rtt_type_new(type, module->stringref_rtts,
  763. &module->rtt_type_lock);
  764. }
  765. #endif
  766. #if WASM_ENABLE_AOT != 0
  767. if (module_inst->module_type == Wasm_Module_AoT) {
  768. AOTModule *module =
  769. (AOTModule *)((AOTModuleInstance *)module_inst)->module;
  770. rtt_type = wasm_stringref_rtt_type_new(type, module->stringref_rtts,
  771. &module->rtt_type_lock);
  772. }
  773. #endif
  774. if (!rtt_type) {
  775. return NULL;
  776. }
  777. if (type == WASM_TYPE_STRINGREF) {
  778. if (!(stringref_obj =
  779. gc_obj_malloc(heap_handle, sizeof(WASMStringrefObject)))) {
  780. return NULL;
  781. }
  782. ((WASMStringrefObjectRef)stringref_obj)->header =
  783. (WASMObjectHeader)rtt_type;
  784. ((WASMStringrefObjectRef)stringref_obj)->str_obj = str_obj;
  785. wasm_obj_set_gc_finalizer(
  786. exec_env, (wasm_obj_t)stringref_obj,
  787. (wasm_obj_finalizer_t)wasm_stringref_obj_finalizer, NULL);
  788. }
  789. else if (type == WASM_TYPE_STRINGVIEWWTF8) {
  790. if (!(stringref_obj = gc_obj_malloc(
  791. heap_handle, sizeof(WASMStringviewWTF8Object)))) {
  792. return NULL;
  793. }
  794. ((WASMStringviewWTF8ObjectRef)stringref_obj)->header =
  795. (WASMObjectHeader)rtt_type;
  796. ((WASMStringviewWTF8ObjectRef)stringref_obj)->str_obj = str_obj;
  797. wasm_obj_set_gc_finalizer(
  798. exec_env, (wasm_obj_t)stringref_obj,
  799. (wasm_obj_finalizer_t)wasm_stringview_wtf8_obj_finalizer, NULL);
  800. }
  801. else if (type == WASM_TYPE_STRINGVIEWWTF16) {
  802. if (!(stringref_obj = gc_obj_malloc(
  803. heap_handle, sizeof(WASMStringviewWTF16Object)))) {
  804. return NULL;
  805. }
  806. ((WASMStringviewWTF16ObjectRef)stringref_obj)->header =
  807. (WASMObjectHeader)rtt_type;
  808. ((WASMStringviewWTF16ObjectRef)stringref_obj)->str_obj = str_obj;
  809. wasm_obj_set_gc_finalizer(
  810. exec_env, (wasm_obj_t)stringref_obj,
  811. (wasm_obj_finalizer_t)wasm_stringview_wtf16_obj_finalizer, NULL);
  812. }
  813. else if (type == WASM_TYPE_STRINGVIEWITER) {
  814. if (!(stringref_obj = gc_obj_malloc(
  815. heap_handle, sizeof(WASMStringviewIterObject)))) {
  816. return NULL;
  817. }
  818. ((WASMStringviewIterObjectRef)stringref_obj)->header =
  819. (WASMObjectHeader)rtt_type;
  820. ((WASMStringviewIterObjectRef)stringref_obj)->str_obj = str_obj;
  821. ((WASMStringviewIterObjectRef)stringref_obj)->pos = pos;
  822. wasm_obj_set_gc_finalizer(
  823. exec_env, (wasm_obj_t)stringref_obj,
  824. (wasm_obj_finalizer_t)wasm_stringview_iter_obj_finalizer, NULL);
  825. }
  826. return stringref_obj;
  827. }
  828. WASMStringrefObjectRef
  829. wasm_stringref_obj_new(WASMExecEnv *exec_env, const void *str_obj)
  830. {
  831. WASMStringrefObjectRef stringref_obj;
  832. stringref_obj = (WASMStringrefObjectRef)stringref_obj_new(
  833. exec_env, WASM_TYPE_STRINGREF, str_obj, 0);
  834. return stringref_obj;
  835. }
  836. WASMStringviewWTF8ObjectRef
  837. wasm_stringview_wtf8_obj_new(WASMExecEnv *exec_env, const void *str_obj)
  838. {
  839. WASMStringviewWTF8ObjectRef stringview_wtf8_obj;
  840. stringview_wtf8_obj = (WASMStringviewWTF8ObjectRef)stringref_obj_new(
  841. exec_env, WASM_TYPE_STRINGVIEWWTF8, str_obj, 0);
  842. return stringview_wtf8_obj;
  843. }
  844. WASMStringviewWTF16ObjectRef
  845. wasm_stringview_wtf16_obj_new(WASMExecEnv *exec_env, const void *str_obj)
  846. {
  847. WASMStringviewWTF16ObjectRef stringview_wtf16_obj;
  848. stringview_wtf16_obj = (WASMStringviewWTF16ObjectRef)stringref_obj_new(
  849. exec_env, WASM_TYPE_STRINGVIEWWTF16, str_obj, 0);
  850. return stringview_wtf16_obj;
  851. }
  852. WASMStringviewIterObjectRef
  853. wasm_stringview_iter_obj_new(WASMExecEnv *exec_env, const void *str_obj,
  854. int32 pos)
  855. {
  856. WASMStringviewIterObjectRef stringview_iter_obj;
  857. stringview_iter_obj = (WASMStringviewIterObjectRef)stringref_obj_new(
  858. exec_env, WASM_TYPE_STRINGVIEWITER, str_obj, pos);
  859. return stringview_iter_obj;
  860. }
  861. const void *
  862. wasm_stringref_obj_get_value(WASMStringrefObjectRef stringref_obj)
  863. {
  864. return stringref_obj->str_obj;
  865. }
  866. const void *
  867. wasm_stringview_wtf8_obj_get_value(
  868. WASMStringviewWTF8ObjectRef stringview_wtf8_obj)
  869. {
  870. return stringview_wtf8_obj->str_obj;
  871. }
  872. const void *
  873. wasm_stringview_wtf16_obj_get_value(
  874. WASMStringviewWTF16ObjectRef stringview_wtf16_obj)
  875. {
  876. return stringview_wtf16_obj->str_obj;
  877. }
  878. const void *
  879. wasm_stringview_iter_obj_get_value(
  880. WASMStringviewIterObjectRef stringview_iter_obj)
  881. {
  882. return stringview_iter_obj->str_obj;
  883. }
  884. int32
  885. wasm_stringview_iter_obj_get_pos(
  886. WASMStringviewIterObjectRef stringview_iter_obj)
  887. {
  888. return stringview_iter_obj->pos;
  889. }
  890. void
  891. wasm_stringview_iter_obj_update_pos(
  892. WASMStringviewIterObjectRef stringview_iter_obj, int32 pos)
  893. {
  894. stringview_iter_obj->pos = pos;
  895. }
  896. #define WASM_OBJ_IS_STRINGREF_IMPL(flag) \
  897. WASMRttTypeRef rtt_type; \
  898. \
  899. bh_assert(obj); \
  900. \
  901. if (wasm_obj_is_i31_externref_or_anyref_obj(obj)) \
  902. return false; \
  903. \
  904. rtt_type = (WASMRttTypeRef)wasm_object_header(obj); \
  905. return rtt_type->type_flag == flag ? true : false
  906. bool
  907. wasm_obj_is_stringref_obj(WASMObjectRef obj)
  908. {
  909. WASM_OBJ_IS_STRINGREF_IMPL(WASM_TYPE_STRINGREF);
  910. }
  911. bool
  912. wasm_obj_is_stringview_wtf8_obj(WASMObjectRef obj)
  913. {
  914. WASM_OBJ_IS_STRINGREF_IMPL(WASM_TYPE_STRINGVIEWWTF8);
  915. }
  916. bool
  917. wasm_obj_is_stringview_wtf16_obj(WASMObjectRef obj)
  918. {
  919. WASM_OBJ_IS_STRINGREF_IMPL(WASM_TYPE_STRINGVIEWWTF16);
  920. }
  921. #undef WASM_OBJ_IS_STRINGREF_IMPL
  922. #endif /* end of WASM_ENABLE_STRINGREF != 0 */