gc_object.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  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. WASMRttTypeRef
  15. wasm_rtt_type_new(WASMType *defined_type, uint32 defined_type_idx,
  16. WASMRttType **rtt_types, uint32 rtt_type_count,
  17. korp_mutex *rtt_type_lock)
  18. {
  19. WASMRttType *rtt_type;
  20. bh_assert(defined_type_idx < rtt_type_count);
  21. os_mutex_lock(rtt_type_lock);
  22. if (rtt_types[defined_type_idx]) {
  23. os_mutex_unlock(rtt_type_lock);
  24. return rtt_types[defined_type_idx];
  25. }
  26. if ((rtt_type = wasm_runtime_malloc(sizeof(WASMRttType)))) {
  27. rtt_type->type_flag = defined_type->type_flag;
  28. rtt_type->inherit_depth = defined_type->inherit_depth;
  29. rtt_type->defined_type = defined_type;
  30. rtt_type->root_type = defined_type->root_type;
  31. rtt_types[defined_type_idx] = rtt_type;
  32. }
  33. os_mutex_unlock(rtt_type_lock);
  34. return rtt_type;
  35. }
  36. static void *
  37. gc_obj_malloc(void *heap_handle, uint64 size)
  38. {
  39. void *mem;
  40. if (size >= UINT32_MAX
  41. || !(mem = mem_allocator_malloc_with_gc(heap_handle, (uint32)size))) {
  42. LOG_WARNING("warning: failed to allocate memory for gc object");
  43. return NULL;
  44. }
  45. memset(mem, 0, (uint32)size);
  46. return mem;
  47. }
  48. static void *
  49. get_gc_heap_handle(WASMExecEnv *exec_env)
  50. {
  51. void *gc_heap_handle = NULL;
  52. WASMModuleInstanceCommon *module_inst = exec_env->module_inst;
  53. #if WASM_ENABLE_INTERP != 0
  54. if (module_inst->module_type == Wasm_Module_Bytecode)
  55. gc_heap_handle = ((WASMModuleInstance *)module_inst)->e->gc_heap_handle;
  56. #endif
  57. #if WASM_ENABLE_AOT != 0
  58. if (module_inst->module_type == Wasm_Module_AoT)
  59. gc_heap_handle = NULL; /* TODO */
  60. #endif
  61. bh_assert(gc_heap_handle);
  62. return gc_heap_handle;
  63. }
  64. WASMStructObjectRef
  65. wasm_struct_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type)
  66. {
  67. void *heap_handle = get_gc_heap_handle(exec_env);
  68. WASMStructObjectRef struct_obj;
  69. WASMStructType *struct_type;
  70. bh_assert(rtt_type->type_flag == WASM_TYPE_STRUCT);
  71. struct_type = (WASMStructType *)rtt_type->defined_type;
  72. if (!(struct_obj = gc_obj_malloc(heap_handle, struct_type->total_size))) {
  73. return NULL;
  74. }
  75. struct_obj->header = (WASMObjectHeader)rtt_type;
  76. return struct_obj;
  77. }
  78. void
  79. wasm_struct_obj_set_field(WASMStructObjectRef struct_obj, uint32 field_idx,
  80. const WASMValue *value)
  81. {
  82. WASMRttTypeRef rtt_type =
  83. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
  84. WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
  85. WASMStructFieldType *field;
  86. uint8 field_size, *field_data;
  87. bh_assert(field_idx < struct_type->field_count);
  88. field = struct_type->fields + field_idx;
  89. field_data = (uint8 *)struct_obj + field->field_offset;
  90. field_size = field->field_size;
  91. if (field_size == 4) {
  92. *(int32 *)field_data = value->i32;
  93. }
  94. else if (field_size == 8) {
  95. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  96. || defined(BUILD_TARGET_X86_32)
  97. *(int64 *)field_data = value->i64;
  98. #else
  99. PUT_I64_TO_ADDR((uint32 *)field_data, value->i64);
  100. #endif
  101. }
  102. else if (field_size == 1) {
  103. *(int8 *)field_data = (int8)value->i32;
  104. }
  105. else if (field_size == 2) {
  106. *(int16 *)field_data = (int16)value->i32;
  107. }
  108. else {
  109. bh_assert(0);
  110. }
  111. }
  112. void
  113. wasm_struct_obj_get_field(const WASMStructObjectRef struct_obj,
  114. uint32 field_idx, bool sign_extend, WASMValue *value)
  115. {
  116. WASMRttTypeRef rtt_type =
  117. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)struct_obj);
  118. WASMStructType *struct_type = (WASMStructType *)rtt_type->defined_type;
  119. WASMStructFieldType *field;
  120. uint8 *field_data, field_size;
  121. bh_assert(field_idx < struct_type->field_count);
  122. field = struct_type->fields + field_idx;
  123. field_data = (uint8 *)struct_obj + field->field_offset;
  124. field_size = field->field_size;
  125. if (field_size == 4) {
  126. value->i32 = *(int32 *)field_data;
  127. }
  128. else if (field_size == 8) {
  129. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  130. || defined(BUILD_TARGET_X86_32)
  131. value->i64 = *(int64 *)field_data;
  132. #else
  133. value->i64 = GET_I64_FROM_ADDR((uint32 *)field_data);
  134. #endif
  135. }
  136. else if (field_size == 1) {
  137. if (sign_extend)
  138. value->i32 = (int32)(*(int8 *)field_data);
  139. else
  140. value->u32 = (uint32)(*(uint8 *)field_data);
  141. }
  142. else if (field_size == 2) {
  143. if (sign_extend)
  144. value->i32 = (int32)(*(int8 *)field_data);
  145. else
  146. value->u32 = (uint32)(*(uint8 *)field_data);
  147. }
  148. else {
  149. bh_assert(0);
  150. }
  151. }
  152. WASMArrayObjectRef
  153. wasm_array_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
  154. uint32 length, WASMValue *init_value)
  155. {
  156. void *heap_handle = get_gc_heap_handle(exec_env);
  157. WASMArrayObjectRef array_obj;
  158. WASMArrayType *array_type;
  159. uint64 total_size;
  160. uint32 elem_size, elem_size_log, i;
  161. bh_assert(rtt_type->type_flag == WASM_TYPE_ARRAY);
  162. if (length >= (1 << 29))
  163. return NULL;
  164. array_type = (WASMArrayType *)rtt_type->defined_type;
  165. if (array_type->elem_type == PACKED_TYPE_I8) {
  166. elem_size = 1;
  167. elem_size_log = 0;
  168. }
  169. else if (array_type->elem_type == PACKED_TYPE_I16) {
  170. elem_size = 2;
  171. elem_size_log = 1;
  172. }
  173. else {
  174. elem_size = wasm_value_type_size(array_type->elem_type);
  175. elem_size_log = (elem_size == 4) ? 2 : 3;
  176. }
  177. total_size =
  178. offsetof(WASMArrayObject, elem_data) + (uint64)elem_size * length;
  179. if (!(array_obj = gc_obj_malloc(heap_handle, total_size))) {
  180. return NULL;
  181. }
  182. array_obj->header = (WASMObjectHeader)rtt_type;
  183. array_obj->length = (length << 2) | elem_size_log;
  184. for (i = 0; i < length; i++) {
  185. if (wasm_is_type_reftype(array_type->elem_type)) {
  186. uint32 *elem_addr =
  187. (uint32 *)array_obj->elem_data + REF_CELL_NUM * i;
  188. PUT_REF_TO_ADDR(elem_addr, init_value->gc_obj);
  189. }
  190. else if (array_type->elem_type == VALUE_TYPE_I32
  191. || array_type->elem_type == VALUE_TYPE_F32) {
  192. ((int32 *)array_obj->elem_data)[i] = init_value->i32;
  193. }
  194. else if (array_type->elem_type == PACKED_TYPE_I8) {
  195. ((int8 *)array_obj->elem_data)[i] = (int8)init_value->i32;
  196. }
  197. else if (array_type->elem_type == PACKED_TYPE_I16) {
  198. ((int16 *)array_obj->elem_data)[i] = (int16)init_value->i32;
  199. }
  200. else {
  201. uint32 *elem_addr = (uint32 *)array_obj->elem_data + 2 * i;
  202. PUT_I64_TO_ADDR(elem_addr, init_value->i64);
  203. }
  204. }
  205. return array_obj;
  206. }
  207. void
  208. wasm_array_obj_set_elem(WASMArrayObjectRef array_obj, uint32 elem_idx,
  209. const WASMValue *value)
  210. {
  211. uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
  212. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
  213. switch (elem_size) {
  214. case 1:
  215. *(int8 *)elem_data = (int8)value->i32;
  216. break;
  217. case 2:
  218. *(int16 *)elem_data = (int16)value->i32;
  219. break;
  220. case 4:
  221. *(int32 *)elem_data = value->i32;
  222. break;
  223. case 8:
  224. PUT_I64_TO_ADDR((uint32 *)elem_data, value->i64);
  225. break;
  226. }
  227. }
  228. void
  229. wasm_array_obj_get_elem(const WASMArrayObjectRef array_obj, uint32 elem_idx,
  230. bool sign_extend, WASMValue *value)
  231. {
  232. uint8 *elem_data = wasm_array_obj_elem_addr(array_obj, elem_idx);
  233. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(array_obj);
  234. switch (elem_size) {
  235. case 1:
  236. value->i32 = sign_extend ? (int32)(*(int8 *)elem_data)
  237. : (int32)(uint32)(*(uint8 *)elem_data);
  238. break;
  239. case 2:
  240. value->i32 = sign_extend ? (int32)(*(int16 *)elem_data)
  241. : (int32)(uint32)(*(uint16 *)elem_data);
  242. break;
  243. case 4:
  244. value->i32 = *(int32 *)elem_data;
  245. break;
  246. case 8:
  247. value->i64 = GET_I64_FROM_ADDR((uint32 *)elem_data);
  248. break;
  249. }
  250. }
  251. void
  252. wasm_array_obj_copy(WASMArrayObjectRef dst_obj, uint32 dst_idx,
  253. WASMArrayObjectRef src_obj, uint32 src_idx, uint32 len)
  254. {
  255. uint8 *dst_data = wasm_array_obj_elem_addr(dst_obj, dst_idx);
  256. uint8 *src_data = wasm_array_obj_elem_addr(src_obj, src_idx);
  257. uint32 elem_size = 1 << wasm_array_obj_elem_size_log(dst_obj);
  258. bh_memmove_s(dst_data, elem_size * len, src_data, elem_size * len);
  259. }
  260. uint32
  261. wasm_array_obj_length(const WASMArrayObjectRef array_obj)
  262. {
  263. return array_obj->length >> WASM_ARRAY_LENGTH_SHIFT;
  264. }
  265. void *
  266. wasm_array_obj_first_elem_addr(const WASMArrayObjectRef array_obj)
  267. {
  268. return array_obj->elem_data;
  269. }
  270. void *
  271. wasm_array_obj_elem_addr(const WASMArrayObjectRef array_obj, uint32 elem_idx)
  272. {
  273. return array_obj->elem_data
  274. + (elem_idx << wasm_array_obj_elem_size_log(array_obj));
  275. }
  276. WASMFuncObjectRef
  277. wasm_func_obj_new_internal(void *heap_handle, WASMRttTypeRef rtt_type,
  278. uint32 func_idx_bound)
  279. {
  280. WASMFuncObjectRef func_obj;
  281. uint64 total_size;
  282. bh_assert(rtt_type->type_flag == WASM_TYPE_FUNC);
  283. total_size = sizeof(WASMFuncObject);
  284. if (!(func_obj = gc_obj_malloc(heap_handle, total_size))) {
  285. return NULL;
  286. }
  287. func_obj->header = (WASMObjectHeader)rtt_type;
  288. func_obj->func_idx_bound = func_idx_bound;
  289. return func_obj;
  290. }
  291. WASMFuncObjectRef
  292. wasm_func_obj_new(WASMExecEnv *exec_env, WASMRttTypeRef rtt_type,
  293. uint32 func_idx_bound)
  294. {
  295. void *heap_handle = get_gc_heap_handle(exec_env);
  296. return wasm_func_obj_new_internal(heap_handle, rtt_type, func_idx_bound);
  297. }
  298. uint32
  299. wasm_func_obj_get_func_idx_bound(const WASMFuncObjectRef func_obj)
  300. {
  301. return func_obj->func_idx_bound;
  302. }
  303. WASMFuncType *
  304. wasm_func_obj_get_func_type(const WASMFuncObjectRef func_obj)
  305. {
  306. WASMRttTypeRef rtt_type =
  307. (WASMRttTypeRef)wasm_object_header((WASMObjectRef)func_obj);
  308. bh_assert(rtt_type->type_flag == WASM_TYPE_FUNC);
  309. return (WASMFuncType *)rtt_type->defined_type;
  310. }
  311. WASMExternrefObjectRef
  312. wasm_externref_obj_new(WASMExecEnv *exec_env, const void *host_obj)
  313. {
  314. void *heap_handle = get_gc_heap_handle(exec_env);
  315. WASMAnyrefObjectRef anyref_obj;
  316. WASMExternrefObjectRef externref_obj;
  317. WASMLocalObjectRef local_ref;
  318. if (!(anyref_obj = gc_obj_malloc(heap_handle, sizeof(WASMAnyrefObject)))) {
  319. return NULL;
  320. }
  321. anyref_obj->header = WASM_OBJ_ANYREF_OBJ_FLAG;
  322. anyref_obj->host_obj = host_obj;
  323. /* Lock anyref_obj in case it is reclaimed when allocating memory below */
  324. wasm_runtime_push_local_object_ref(exec_env, &local_ref);
  325. local_ref.val = (WASMObjectRef)anyref_obj;
  326. if (!(externref_obj =
  327. gc_obj_malloc(heap_handle, sizeof(WASMExternrefObject)))) {
  328. wasm_runtime_pop_local_object_ref(exec_env);
  329. return NULL;
  330. }
  331. externref_obj->header = WASM_OBJ_EXTERNREF_OBJ_FLAG;
  332. externref_obj->internal_obj = (WASMObjectRef)anyref_obj;
  333. wasm_runtime_pop_local_object_ref(exec_env);
  334. return externref_obj;
  335. }
  336. WASMAnyrefObjectRef
  337. wasm_anyref_obj_new(WASMExecEnv *exec_env, const void *host_obj)
  338. {
  339. void *heap_handle = get_gc_heap_handle(exec_env);
  340. WASMAnyrefObjectRef anyref_obj;
  341. if (!(anyref_obj = gc_obj_malloc(heap_handle, sizeof(WASMAnyrefObject)))) {
  342. return NULL;
  343. }
  344. anyref_obj->header = WASM_OBJ_ANYREF_OBJ_FLAG;
  345. anyref_obj->host_obj = host_obj;
  346. return anyref_obj;
  347. }
  348. WASMObjectRef
  349. wasm_externref_obj_to_internal_obj(WASMExternrefObjectRef externref_obj)
  350. {
  351. return externref_obj->internal_obj;
  352. }
  353. WASMExternrefObjectRef
  354. wasm_internal_obj_to_externref_obj(WASMExecEnv *exec_env,
  355. WASMObjectRef internal_obj)
  356. {
  357. void *heap_handle = get_gc_heap_handle(exec_env);
  358. WASMExternrefObjectRef externref_obj;
  359. if (!(externref_obj =
  360. gc_obj_malloc(heap_handle, sizeof(WASMExternrefObject)))) {
  361. return NULL;
  362. }
  363. externref_obj->header = WASM_OBJ_EXTERNREF_OBJ_FLAG;
  364. externref_obj->internal_obj = internal_obj;
  365. return externref_obj;
  366. }
  367. const void *
  368. wasm_anyref_obj_get_value(WASMAnyrefObjectRef anyref_obj)
  369. {
  370. return anyref_obj->host_obj;
  371. }
  372. const void *
  373. wasm_externref_obj_get_value(const WASMExternrefObjectRef externref_obj)
  374. {
  375. if (wasm_obj_is_anyref_obj(externref_obj->internal_obj))
  376. return ((WASMAnyrefObjectRef)externref_obj->internal_obj)->host_obj;
  377. else
  378. return externref_obj->internal_obj;
  379. }
  380. WASMI31ObjectRef
  381. wasm_i31_obj_new(uint32 i31_value)
  382. {
  383. return (WASMI31ObjectRef)((i31_value << 1) | 1);
  384. }
  385. uint32
  386. wasm_i31_obj_get_value(WASMI31ObjectRef i31_obj, bool sign_extend)
  387. {
  388. uint32 i31_value = (uint32)(((uintptr_t)i31_obj) >> 1);
  389. if (sign_extend && (i31_value & 0x40000000)) /* bit 30 is 1 */
  390. /* set bit 31 to 1 */
  391. i31_value |= 0x80000000;
  392. return i31_value;
  393. }
  394. bool
  395. wasm_obj_is_i31_obj(WASMObjectRef obj)
  396. {
  397. bh_assert(obj);
  398. return (((uintptr_t)obj) & 1) ? true : false;
  399. }
  400. bool
  401. wasm_obj_is_externref_obj(WASMObjectRef obj)
  402. {
  403. bh_assert(obj);
  404. return (!wasm_obj_is_i31_obj(obj)
  405. && (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG))
  406. ? true
  407. : false;
  408. }
  409. bool
  410. wasm_obj_is_anyref_obj(WASMObjectRef obj)
  411. {
  412. bh_assert(obj);
  413. return (!wasm_obj_is_i31_obj(obj)
  414. && (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG))
  415. ? true
  416. : false;
  417. }
  418. bool
  419. wasm_obj_is_i31_externref_or_anyref_obj(WASMObjectRef obj)
  420. {
  421. bh_assert(obj);
  422. return (wasm_obj_is_i31_obj(obj)
  423. || (obj->header
  424. & (WASM_OBJ_EXTERNREF_OBJ_FLAG | WASM_OBJ_ANYREF_OBJ_FLAG)))
  425. ? true
  426. : false;
  427. }
  428. bool
  429. wasm_obj_is_struct_obj(WASMObjectRef obj)
  430. {
  431. WASMRttTypeRef rtt_type;
  432. bh_assert(obj);
  433. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  434. return false;
  435. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  436. return rtt_type->type_flag == WASM_TYPE_STRUCT ? true : false;
  437. }
  438. bool
  439. wasm_obj_is_array_obj(WASMObjectRef obj)
  440. {
  441. WASMRttTypeRef rtt_type;
  442. bh_assert(obj);
  443. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  444. return false;
  445. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  446. return rtt_type->type_flag == WASM_TYPE_ARRAY ? true : false;
  447. }
  448. bool
  449. wasm_obj_is_func_obj(WASMObjectRef obj)
  450. {
  451. WASMRttTypeRef rtt_type;
  452. bh_assert(obj);
  453. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  454. return false;
  455. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  456. return rtt_type->type_flag == WASM_TYPE_FUNC ? true : false;
  457. }
  458. bool
  459. wasm_obj_is_internal_obj(WASMObjectRef obj)
  460. {
  461. WASMRttTypeRef rtt_type;
  462. bh_assert(obj);
  463. if (wasm_obj_is_i31_obj(obj))
  464. return true;
  465. else if (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG)
  466. return true;
  467. else if (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG)
  468. return false;
  469. else {
  470. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  471. return (rtt_type->type_flag == WASM_TYPE_STRUCT
  472. || rtt_type->type_flag == WASM_TYPE_ARRAY)
  473. ? true
  474. : false;
  475. }
  476. }
  477. bool
  478. wasm_obj_is_eq_obj(WASMObjectRef obj)
  479. {
  480. WASMRttTypeRef rtt_type;
  481. bh_assert(obj);
  482. if (wasm_obj_is_i31_obj(obj))
  483. return true;
  484. else if ((obj->header & WASM_OBJ_ANYREF_OBJ_FLAG)
  485. || (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG))
  486. return false;
  487. else {
  488. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  489. return (rtt_type->type_flag == WASM_TYPE_STRUCT
  490. || rtt_type->type_flag == WASM_TYPE_ARRAY)
  491. ? true
  492. : false;
  493. }
  494. }
  495. bool
  496. wasm_obj_is_created_from_heap(WASMObjectRef obj)
  497. {
  498. if (obj == NULL)
  499. return false;
  500. if (wasm_obj_is_i31_obj(obj))
  501. return false;
  502. /* struct/array/func/externref/anyref object */
  503. return true;
  504. }
  505. bool
  506. wasm_obj_is_instance_of(WASMObjectRef obj, uint32 type_idx, WASMType **types,
  507. uint32 type_count)
  508. {
  509. WASMRttTypeRef rtt_type_sub;
  510. WASMType *type_sub, *type_parent;
  511. uint32 distance, i;
  512. bh_assert(obj);
  513. bh_assert(type_idx < type_count);
  514. if (wasm_obj_is_i31_externref_or_anyref_obj(obj))
  515. return false;
  516. rtt_type_sub = (WASMRttTypeRef)wasm_object_header(obj);
  517. type_parent = types[type_idx];
  518. if (!(rtt_type_sub->root_type == type_parent->root_type
  519. && rtt_type_sub->inherit_depth >= type_parent->inherit_depth))
  520. return false;
  521. type_sub = rtt_type_sub->defined_type;
  522. distance = type_sub->inherit_depth - type_parent->inherit_depth;
  523. for (i = 0; i < distance; i++) {
  524. type_sub = type_sub->parent_type;
  525. }
  526. return (type_sub == type_parent) ? true : false;
  527. }
  528. bool
  529. wasm_obj_is_type_of(WASMObjectRef obj, int32 heap_type)
  530. {
  531. bh_assert(obj);
  532. switch (heap_type) {
  533. case HEAP_TYPE_FUNC:
  534. return wasm_obj_is_func_obj(obj);
  535. case HEAP_TYPE_EXTERN:
  536. return wasm_obj_is_externref_obj(obj);
  537. case HEAP_TYPE_ANY:
  538. return wasm_obj_is_internal_obj(obj);
  539. case HEAP_TYPE_EQ:
  540. return wasm_obj_is_eq_obj(obj);
  541. case HEAP_TYPE_I31:
  542. return wasm_obj_is_i31_obj(obj);
  543. case HEAP_TYPE_STRUCT:
  544. return wasm_obj_is_struct_obj(obj);
  545. case HEAP_TYPE_ARRAY:
  546. return wasm_obj_is_array_obj(obj);
  547. case HEAP_TYPE_NONE:
  548. case HEAP_TYPE_NOFUNC:
  549. case HEAP_TYPE_NOEXTERN:
  550. return false;
  551. default:
  552. bh_assert(0);
  553. break;
  554. }
  555. return false;
  556. }
  557. bool
  558. wasm_obj_equal(WASMObjectRef obj1, WASMObjectRef obj2)
  559. {
  560. /* TODO: do we need to compare the internal details of the objects */
  561. return obj1 == obj2 ? true : false;
  562. }
  563. bool
  564. wasm_object_get_ref_list(WASMObjectRef obj, bool *p_is_compact_mode,
  565. uint32 *p_ref_num, uint16 **p_ref_list,
  566. uint32 *p_ref_start_offset)
  567. {
  568. WASMRttTypeRef rtt_type;
  569. bh_assert(wasm_obj_is_created_from_heap(obj));
  570. rtt_type = (WASMRttTypeRef)wasm_object_header(obj);
  571. if (obj->header & WASM_OBJ_EXTERNREF_OBJ_FLAG) {
  572. /* externref object */
  573. static uint16 externref_obj_ref_list[] = { (uint16)offsetof(
  574. WASMExternrefObject, internal_obj) };
  575. *p_is_compact_mode = false;
  576. *p_ref_num = 0;
  577. *p_ref_list = externref_obj_ref_list;
  578. return true;
  579. }
  580. else if (obj->header & WASM_OBJ_ANYREF_OBJ_FLAG) {
  581. /* anyref object */
  582. *p_is_compact_mode = false;
  583. *p_ref_num = 0;
  584. *p_ref_list = NULL;
  585. return true;
  586. }
  587. else if (rtt_type->defined_type->type_flag == WASM_TYPE_FUNC) {
  588. /* function object */
  589. *p_is_compact_mode = false;
  590. *p_ref_num = 0;
  591. *p_ref_list = NULL;
  592. return true;
  593. }
  594. else if (rtt_type->defined_type->type_flag == WASM_TYPE_STRUCT) {
  595. /* struct object */
  596. WASMStructType *type = (WASMStructType *)rtt_type->defined_type;
  597. *p_is_compact_mode = false;
  598. *p_ref_num = *type->reference_table;
  599. *p_ref_list = type->reference_table + 1;
  600. return true;
  601. }
  602. else if (rtt_type->defined_type->type_flag == WASM_TYPE_ARRAY) {
  603. /* array object */
  604. *p_is_compact_mode = true;
  605. *p_ref_num = (uint16)wasm_array_obj_length((WASMArrayObjectRef)obj);
  606. *p_ref_start_offset = (uint16)offsetof(WASMArrayObject, elem_data);
  607. return true;
  608. }
  609. else {
  610. bh_assert(0);
  611. return false;
  612. }
  613. }