PageRenderTime 27ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/tool/gec/runtime/c/ge_types.c

http://github.com/gobo-eiffel/gobo
C | 670 lines | 467 code | 54 blank | 149 comment | 61 complexity | 65f170e54b8ac9aa09530cd9c0ae8645 MD5 | raw file
  1. /*
  2. description:
  3. "C functions used to implement type information"
  4. system: "Gobo Eiffel Compiler"
  5. copyright: "Copyright (c) 2016-2018, Eric Bezault and others"
  6. license: "MIT License"
  7. date: "$Date$"
  8. revision: "$Revision$"
  9. */
  10. #ifndef GE_TYPES_C
  11. #define GE_TYPES_C
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1020)
  13. #pragma once
  14. #endif
  15. #ifndef GE_TYPES_H
  16. #include "ge_types.h"
  17. #endif
  18. #ifndef GE_STRING_H
  19. #include "ge_string.h"
  20. #endif
  21. #ifdef __cplusplus
  22. extern "C" {
  23. #endif
  24. /*
  25. * Number of type infos in `GE_type_infos'.
  26. * Do not take into account the fake item at index 0.
  27. */
  28. int GE_type_info_count;
  29. /*
  30. * Encode a EIF_TYPE into a EIF_ENCODED_TYPE.
  31. * The lower part of EIF_ENCODED_TYPE contains the .id field,
  32. * and the upper part the .annotations.
  33. */
  34. EIF_ENCODED_TYPE GE_encoded_type(EIF_TYPE a_type)
  35. {
  36. EIF_ENCODED_TYPE l_result;
  37. #if defined(_MSC_VER)
  38. /* This code below is just optimized as one move by cl on x86 platforms.
  39. * The else-part below generates non-optimal code with cl.
  40. */
  41. memcpy(&l_result, &a_type, sizeof(EIF_ENCODED_TYPE));
  42. #else
  43. /* This code below is just optimized as one move by gcc/clang on x86 platforms. */
  44. l_result = a_type.annotations;
  45. l_result = (l_result << 16) | a_type.id;
  46. #endif
  47. return l_result;
  48. }
  49. /*
  50. * Decode a EIF_ENCODED_TYPE into a EIF_TYPE.
  51. * The lower part of EIF_ENCODED_TYPE contains the .id field,
  52. * and the upper part the .annotations.
  53. */
  54. EIF_TYPE GE_decoded_type(EIF_ENCODED_TYPE a_type)
  55. {
  56. EIF_TYPE l_result;
  57. #if defined(_MSC_VER)
  58. /* This code below is just optimized as one move by cl on x86 platforms.
  59. * The else-part below generates non-optimal code with cl.
  60. */
  61. memcpy(&l_result, &a_type, sizeof(EIF_TYPE));
  62. #else
  63. /* This code below is just optimized as one move by gcc/clang on x86 platforms. */
  64. l_result.id = a_type & 0x0000FFFF;
  65. l_result.annotations = a_type >> 16;
  66. #endif
  67. return l_result;
  68. }
  69. /*
  70. * Type with `a_id' and `a_annotations'.
  71. */
  72. EIF_TYPE GE_new_type(EIF_TYPE_INDEX a_id, EIF_TYPE_INDEX a_annotations)
  73. {
  74. EIF_TYPE l_result;
  75. l_result.id = a_id;
  76. l_result.annotations = a_annotations;
  77. return l_result;
  78. }
  79. /*
  80. * Associated detachable type of `a_type' if any,
  81. * otherwise `a_type'.
  82. */
  83. EIF_TYPE GE_non_attached_type(EIF_TYPE a_type)
  84. {
  85. /* Since types are by default detachable, we simply remove
  86. * all attachment marks. */
  87. a_type.annotations &= ~(ATTACHED_FLAG | DETACHABLE_FLAG);
  88. return a_type;
  89. }
  90. /*
  91. * Associated attached type of `a_type' if any,
  92. * otherwise `a_type'.
  93. */
  94. EIF_TYPE GE_attached_type(EIF_TYPE a_type)
  95. {
  96. if (!GE_is_expanded_type_index(a_type.id)) {
  97. a_type.annotations &= ~DETACHABLE_FLAG;
  98. a_type.annotations |= ATTACHED_FLAG;
  99. }
  100. return a_type;
  101. }
  102. /*
  103. * Is `a_type' a SPECIAL type of user-defined expanded type?
  104. */
  105. EIF_BOOLEAN GE_is_special_of_expanded_type_index(EIF_TYPE_INDEX a_type)
  106. {
  107. EIF_BOOLEAN l_result = EIF_FALSE;
  108. #ifdef GE_USE_TYPE_GENERIC_PARAMETERS
  109. EIF_TYPE_INDEX l_generic_parameter;
  110. uint32_t l_flags;
  111. if ((GE_type_infos[a_type].flags & GE_TYPE_FLAG_SPECIAL)) {
  112. l_generic_parameter = GE_decoded_type(GE_type_infos[a_type].generic_parameters[0]).id;
  113. l_flags = GE_type_infos[l_generic_parameter].flags;
  114. l_result = EIF_TEST((l_flags & GE_TYPE_FLAG_EXPANDED) && !(l_flags & GE_TYPE_FLAG_BASIC_MASK));
  115. }
  116. #endif
  117. return l_result;
  118. }
  119. /*
  120. * Is `a_type' a SPECIAL type of reference type?
  121. */
  122. EIF_BOOLEAN GE_is_special_of_reference_type_index(EIF_TYPE_INDEX a_type)
  123. {
  124. EIF_BOOLEAN l_result = EIF_FALSE;
  125. #ifdef GE_USE_TYPE_GENERIC_PARAMETERS
  126. EIF_TYPE_INDEX l_generic_parameter;
  127. uint32_t l_flags;
  128. if ((GE_type_infos[a_type].flags & GE_TYPE_FLAG_SPECIAL)) {
  129. l_generic_parameter = GE_decoded_type(GE_type_infos[a_type].generic_parameters[0]).id;
  130. l_flags = GE_type_infos[l_generic_parameter].flags;
  131. l_result = EIF_TEST(!(l_flags & GE_TYPE_FLAG_EXPANDED));
  132. }
  133. #endif
  134. return l_result;
  135. }
  136. /*
  137. * Is `a_type' a SPECIAL type of reference type or basic expanded type?
  138. * (Note that user-defined expanded types are excluded.)
  139. */
  140. EIF_BOOLEAN GE_is_special_of_reference_or_basic_expanded_type_index(EIF_TYPE_INDEX a_type)
  141. {
  142. EIF_BOOLEAN l_result = EIF_FALSE;
  143. #ifdef GE_USE_TYPE_GENERIC_PARAMETERS
  144. EIF_TYPE_INDEX l_generic_parameter;
  145. uint32_t l_flags;
  146. if ((GE_type_infos[a_type].flags & GE_TYPE_FLAG_SPECIAL)) {
  147. l_generic_parameter = GE_decoded_type(GE_type_infos[a_type].generic_parameters[0]).id;
  148. l_flags = GE_type_infos[l_generic_parameter].flags;
  149. l_result = EIF_TEST(!(l_flags & GE_TYPE_FLAG_EXPANDED) || (l_flags & GE_TYPE_FLAG_BASIC_MASK));
  150. }
  151. #endif
  152. return l_result;
  153. }
  154. /*
  155. * Does `i'-th field of `a_object + a_physical_offset' (which is expected to be reference)
  156. * denote a reference with copy semantics?
  157. */
  158. EIF_BOOLEAN GE_is_copy_semantics_field(EIF_INTEGER i, EIF_POINTER a_object, EIF_INTEGER a_physical_offset)
  159. {
  160. EIF_REFERENCE l_object;
  161. l_object = GE_reference_field(i, a_object, a_physical_offset);
  162. if (l_object) {
  163. return GE_is_expanded_object(l_object);
  164. } else {
  165. return EIF_FALSE;
  166. }
  167. }
  168. /*
  169. * Does `i'-th item of special `a_object' (which is expected to be reference)
  170. * denote a reference with copy semantics?
  171. */
  172. EIF_BOOLEAN GE_is_special_copy_semantics_item(EIF_INTEGER i, EIF_POINTER a_object)
  173. {
  174. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_OFFSET)
  175. EIF_REFERENCE l_object;
  176. GE_type_info l_type_info;
  177. l_type_info = GE_type_infos[((EIF_REFERENCE)a_object)->id];
  178. /* The last pseudo attribute is the item at index 0 in the special object */
  179. l_object = *(EIF_REFERENCE*)((char*)a_object + l_type_info.attributes[l_type_info.attribute_count - 1]->offset + i * sizeof(EIF_REFERENCE));
  180. if (l_object) {
  181. return GE_is_expanded_object(l_object);
  182. } else {
  183. return EIF_FALSE;
  184. }
  185. #else
  186. return EIF_FALSE;
  187. #endif
  188. }
  189. /*
  190. * Generator class name of `a_type'.
  191. */
  192. EIF_REFERENCE GE_generator_of_type_index(EIF_TYPE_INDEX a_type)
  193. {
  194. const char* l_generator;
  195. #ifdef GE_USE_TYPE_GENERATOR
  196. /* TODO: check that `a_type' is valid. */
  197. l_generator = GE_type_infos[a_type].generator;
  198. #else
  199. l_generator = "";
  200. #endif
  201. return GE_str(l_generator);
  202. }
  203. EIF_REFERENCE GE_generator_8_of_type_index(EIF_TYPE_INDEX a_type)
  204. {
  205. const char* l_generator;
  206. #ifdef GE_USE_TYPE_GENERATOR
  207. /* TODO: check that `a_type' is valid. */
  208. l_generator = GE_type_infos[a_type].generator;
  209. #else
  210. l_generator = "";
  211. #endif
  212. return GE_str8(l_generator);
  213. }
  214. /*
  215. * Full name of `a_type'.
  216. */
  217. EIF_REFERENCE GE_generating_type_of_encoded_type(EIF_ENCODED_TYPE a_type)
  218. {
  219. const char* l_name;
  220. #ifdef GE_USE_TYPE_NAME
  221. /* TODO: check that `a_type' is valid. */
  222. EIF_TYPE l_decoded_type;
  223. l_decoded_type = GE_decoded_type(a_type);
  224. l_name = GE_type_infos[l_decoded_type.id].name;
  225. if (!l_decoded_type.annotations) {
  226. l_name++;
  227. }
  228. #else
  229. l_name = "";
  230. #endif
  231. return GE_str(l_name);
  232. }
  233. EIF_REFERENCE GE_generating_type_8_of_encoded_type(EIF_ENCODED_TYPE a_type)
  234. {
  235. const char* l_name;
  236. #ifdef GE_USE_TYPE_NAME
  237. /* TODO: check that `a_type' is valid. */
  238. EIF_TYPE l_decoded_type;
  239. l_decoded_type = GE_decoded_type(a_type);
  240. l_name = GE_type_infos[l_decoded_type.id].name;
  241. if (!l_decoded_type.annotations) {
  242. l_name++;
  243. }
  244. #else
  245. l_name = "";
  246. #endif
  247. return GE_str8(l_name);
  248. }
  249. /*
  250. * Encoded type whose name is `a_name'.
  251. * -1 if no such type.
  252. */
  253. EIF_ENCODED_TYPE GE_encoded_type_from_name(EIF_POINTER a_name)
  254. {
  255. #ifdef GE_USE_TYPE_NAME
  256. /* TODO: check that `a_type' is valid. */
  257. int i;
  258. const char* l_name;
  259. for (i = 1; i <= GE_type_info_count; i++) {
  260. l_name = GE_type_infos[i].name;
  261. if (strcmp((char*)a_name, l_name + 1) == 0) {
  262. return (EIF_INTEGER)GE_encoded_type(GE_new_type(i, 0x0));
  263. } else if (strcmp((char*)a_name, l_name) == 0) {
  264. return (EIF_INTEGER)GE_encoded_type(GE_new_type(i, ATTACHED_FLAG));
  265. }
  266. }
  267. #endif
  268. return EIF_NO_TYPE;
  269. }
  270. /*
  271. * Does `a_type_1' conform to `a_type_2'?
  272. */
  273. EIF_BOOLEAN GE_encoded_type_conforms_to(EIF_ENCODED_TYPE a_type_1, EIF_ENCODED_TYPE a_type_2)
  274. {
  275. #ifdef GE_USE_ANCESTORS
  276. GE_type_info l_type_info_1, l_type_info_2;
  277. GE_ancestor** l_ancestors;
  278. uint32_t l_ancestor_count, i;
  279. EIF_TYPE l_decoded_type_1, l_decoded_type_2;
  280. EIF_TYPE_INDEX l_type_index_1, l_type_index_2, l_ancestor_type_index;
  281. uint32_t l_flags_1, l_flags_2;
  282. l_decoded_type_1 = GE_decoded_type(a_type_1);
  283. l_decoded_type_2 = GE_decoded_type(a_type_2);
  284. l_type_index_1 = l_decoded_type_1.id;
  285. l_type_index_2 = l_decoded_type_2.id;
  286. l_type_info_1 = GE_type_infos[l_type_index_1];
  287. l_type_info_2 = GE_type_infos[l_type_index_2];
  288. l_flags_1 = l_type_info_1.flags;
  289. l_flags_2 = l_type_info_2.flags;
  290. if (!(l_flags_1 & GE_TYPE_FLAG_EXPANDED || l_decoded_type_1.annotations & ATTACHED_FLAG) && (l_flags_2 & GE_TYPE_FLAG_EXPANDED || l_decoded_type_2.annotations & ATTACHED_FLAG)) {
  291. return EIF_FALSE;
  292. } else if (l_flags_1 & GE_TYPE_FLAG_NONE) {
  293. return EIF_TEST(!(l_flags_2 & GE_TYPE_FLAG_EXPANDED));
  294. } else if (l_type_index_1 == l_type_index_2) {
  295. return EIF_TRUE;
  296. } else if (l_type_index_1 < l_type_index_2) {
  297. return EIF_FALSE;
  298. } else {
  299. l_ancestors = l_type_info_1.ancestors;
  300. l_ancestor_count = l_type_info_1.ancestor_count;
  301. for (i = 0; i < l_ancestor_count; i++) {
  302. l_ancestor_type_index = l_ancestors[i]->type_id;
  303. if (l_ancestor_type_index == l_type_index_2) {
  304. return EIF_TRUE;
  305. } else if (l_ancestor_type_index > l_type_index_2) {
  306. return EIF_FALSE;
  307. }
  308. }
  309. }
  310. #endif
  311. return EIF_FALSE;
  312. }
  313. /*
  314. * Number of generic parameters.
  315. */
  316. EIF_INTEGER GE_generic_parameter_count_of_type_index(EIF_TYPE_INDEX a_type)
  317. {
  318. #ifdef GE_USE_TYPE_GENERIC_PARAMETERS
  319. return (EIF_INTEGER)GE_type_infos[a_type].generic_parameter_count;
  320. #else
  321. return (EIF_INTEGER)0;
  322. #endif
  323. }
  324. /*
  325. * Type of `i'-th generic parameter of `a_type'.
  326. */
  327. EIF_INTEGER GE_generic_parameter_of_type_index(EIF_TYPE_INDEX a_type, EIF_INTEGER i)
  328. {
  329. #ifdef GE_USE_TYPE_GENERIC_PARAMETERS
  330. /* TODO: check that `a_type' and `i' are valid. */
  331. return (EIF_INTEGER)GE_type_infos[a_type].generic_parameters[i - 1];
  332. #else
  333. return (EIF_INTEGER)0;
  334. #endif
  335. }
  336. /*
  337. * Number of fields of an object of dynamic type `a_type'.
  338. */
  339. EIF_INTEGER GE_field_count_of_type_index(EIF_TYPE_INDEX a_type)
  340. {
  341. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_OFFSET)
  342. /* TODO: check that `a_type' is valid. */
  343. return (EIF_INTEGER)GE_type_infos[a_type].attribute_count;
  344. #else
  345. return (EIF_INTEGER)0;
  346. #endif
  347. }
  348. /*
  349. * Physical offset of the `i'-th field for an object of dynamic type `a_type'.
  350. */
  351. EIF_INTEGER GE_field_offset_of_type_index(EIF_INTEGER i, EIF_TYPE_INDEX a_type)
  352. {
  353. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_OFFSET)
  354. /* TODO: check that `a_type' and `i' are valid. */
  355. return (EIF_INTEGER)GE_type_infos[a_type].attributes[i - 1]->offset;
  356. #else
  357. return (EIF_INTEGER)0;
  358. #endif
  359. }
  360. /*
  361. * Name of the `i'-th field for an object of dynamic type `a_type'.
  362. */
  363. EIF_POINTER GE_field_name_of_type_index(EIF_INTEGER i, EIF_TYPE_INDEX a_type)
  364. {
  365. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_NAME)
  366. /* TODO: check that `a_type' and `i' are valid. */
  367. return (EIF_POINTER)GE_type_infos[a_type].attributes[i - 1]->name;
  368. #else
  369. return (EIF_POINTER)0;
  370. #endif
  371. }
  372. /*
  373. * Static type of the `i'-th field for an object of dynamic type `a_type'.
  374. */
  375. EIF_INTEGER GE_field_static_type_of_type_index(EIF_INTEGER i, EIF_TYPE_INDEX a_type)
  376. {
  377. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_TYPE_ID)
  378. /* TODO: check that `a_type' and `i' are valid. */
  379. return (EIF_INTEGER)GE_type_infos[a_type].attributes[i - 1]->type_id;
  380. #else
  381. return (EIF_INTEGER)0;
  382. #endif
  383. }
  384. /*
  385. * Kind of type of the `i'-th field for an object of dynamic type `a_type'.
  386. */
  387. EIF_INTEGER GE_field_type_kind_of_type_index(EIF_INTEGER i, EIF_TYPE_INDEX a_type)
  388. {
  389. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_TYPE_ID)
  390. uint32_t l_flags = GE_type_infos[GE_decoded_type(GE_type_infos[a_type].attributes[i - 1]->type_id).id].flags;
  391. if (l_flags & GE_TYPE_FLAG_BASIC_MASK) {
  392. switch (l_flags & GE_TYPE_FLAG_BASIC_MASK) {
  393. case GE_TYPE_FLAG_BOOLEAN:
  394. return (EIF_INTEGER)GE_TYPE_KIND_BOOLEAN;
  395. case GE_TYPE_FLAG_CHARACTER_8:
  396. return (EIF_INTEGER)GE_TYPE_KIND_CHARACTER_8;
  397. case GE_TYPE_FLAG_CHARACTER_32:
  398. return (EIF_INTEGER)GE_TYPE_KIND_CHARACTER_32;
  399. case GE_TYPE_FLAG_INTEGER_8:
  400. return (EIF_INTEGER)GE_TYPE_KIND_INTEGER_8;
  401. case GE_TYPE_FLAG_INTEGER_16:
  402. return (EIF_INTEGER)GE_TYPE_KIND_INTEGER_16;
  403. case GE_TYPE_FLAG_INTEGER_32:
  404. return (EIF_INTEGER)GE_TYPE_KIND_INTEGER_32;
  405. case GE_TYPE_FLAG_INTEGER_64:
  406. return (EIF_INTEGER)GE_TYPE_KIND_INTEGER_64;
  407. case GE_TYPE_FLAG_NATURAL_8:
  408. return (EIF_INTEGER)GE_TYPE_KIND_NATURAL_8;
  409. case GE_TYPE_FLAG_NATURAL_16:
  410. return (EIF_INTEGER)GE_TYPE_KIND_NATURAL_16;
  411. case GE_TYPE_FLAG_NATURAL_32:
  412. return (EIF_INTEGER)GE_TYPE_KIND_NATURAL_32;
  413. case GE_TYPE_FLAG_NATURAL_64:
  414. return (EIF_INTEGER)GE_TYPE_KIND_NATURAL_64;
  415. case GE_TYPE_FLAG_POINTER:
  416. return (EIF_INTEGER)GE_TYPE_KIND_POINTER;
  417. case GE_TYPE_FLAG_REAL_32:
  418. return (EIF_INTEGER)GE_TYPE_KIND_REAL_32;
  419. case GE_TYPE_FLAG_REAL_64:
  420. return (EIF_INTEGER)GE_TYPE_KIND_REAL_64;
  421. default:
  422. return (EIF_INTEGER)GE_TYPE_KIND_INVALID;
  423. }
  424. } else if (l_flags & GE_TYPE_FLAG_EXPANDED) {
  425. return (EIF_INTEGER)GE_TYPE_KIND_EXPANDED;
  426. } else {
  427. return (EIF_INTEGER)GE_TYPE_KIND_REFERENCE;
  428. }
  429. #else
  430. return (EIF_INTEGER)GE_TYPE_KIND_INVALID;
  431. #endif
  432. }
  433. /*
  434. * Physical size of `a_object'.
  435. */
  436. EIF_NATURAL_64 GE_object_size(EIF_POINTER a_object)
  437. {
  438. #ifdef GE_USE_TYPE_OBJECT_SIZE
  439. EIF_TYPE_INDEX l_type_index = ((EIF_REFERENCE)(a_object))->id;
  440. uint64_t l_size = GE_type_infos[l_type_index].object_size;
  441. #ifdef GE_USE_TYPE_GENERIC_PARAMETERS
  442. if (GE_is_special_type_index(l_type_index)) {
  443. EIF_TYPE_INDEX l_generic_parameter = GE_decoded_type(GE_type_infos[l_type_index].generic_parameters[0]).id;
  444. uint32_t l_flags = GE_type_infos[l_generic_parameter].flags;
  445. EIF_INTEGER l_capacity = ((EIF_SPECIAL*)a_object)->capacity;
  446. uint64_t l_item_size;
  447. if (l_flags & GE_TYPE_FLAG_BASIC_MASK) {
  448. switch (l_flags & GE_TYPE_FLAG_BASIC_MASK) {
  449. case GE_TYPE_FLAG_BOOLEAN:
  450. l_item_size = sizeof(EIF_BOOLEAN);
  451. break;
  452. case GE_TYPE_FLAG_CHARACTER_8:
  453. l_item_size = sizeof(EIF_CHARACTER_8);
  454. break;
  455. case GE_TYPE_FLAG_CHARACTER_32:
  456. l_item_size = sizeof(EIF_CHARACTER_32);
  457. break;
  458. case GE_TYPE_FLAG_INTEGER_8:
  459. l_item_size = sizeof(EIF_INTEGER_8);
  460. break;
  461. case GE_TYPE_FLAG_INTEGER_16:
  462. l_item_size = sizeof(EIF_INTEGER_16);
  463. break;
  464. case GE_TYPE_FLAG_INTEGER_32:
  465. l_item_size = sizeof(EIF_INTEGER_32);
  466. break;
  467. case GE_TYPE_FLAG_INTEGER_64:
  468. l_item_size = sizeof(EIF_INTEGER_64);
  469. break;
  470. case GE_TYPE_FLAG_NATURAL_8:
  471. l_item_size = sizeof(EIF_NATURAL_8);
  472. break;
  473. case GE_TYPE_FLAG_NATURAL_16:
  474. l_item_size = sizeof(EIF_NATURAL_16);
  475. break;
  476. case GE_TYPE_FLAG_NATURAL_32:
  477. l_item_size = sizeof(EIF_NATURAL_32);
  478. break;
  479. case GE_TYPE_FLAG_NATURAL_64:
  480. l_item_size = sizeof(EIF_NATURAL_64);
  481. break;
  482. case GE_TYPE_FLAG_POINTER:
  483. l_item_size = sizeof(EIF_POINTER);
  484. break;
  485. case GE_TYPE_FLAG_REAL_32:
  486. l_item_size = sizeof(EIF_REAL_32);
  487. break;
  488. case GE_TYPE_FLAG_REAL_64:
  489. l_item_size = sizeof(EIF_REAL_64);
  490. break;
  491. default:
  492. l_item_size = 0;
  493. }
  494. } else if (l_flags & GE_TYPE_FLAG_EXPANDED) {
  495. l_item_size = GE_type_infos[l_generic_parameter].object_size;
  496. } else {
  497. l_item_size = sizeof(EIF_REFERENCE);
  498. }
  499. l_size += l_capacity * l_item_size;
  500. }
  501. #endif
  502. return (EIF_NATURAL_64)l_size;
  503. #else
  504. return (EIF_NATURAL_64)0;
  505. #endif
  506. }
  507. /*
  508. * Is `i'-th field of objects of type `a_type' a user-defined expanded attribute?
  509. */
  510. EIF_BOOLEAN GE_is_field_expanded_of_type_index(EIF_INTEGER i, EIF_TYPE_INDEX a_type)
  511. {
  512. #if defined(GE_USE_ATTRIBUTES) && defined(GE_USE_ATTRIBUTE_TYPE_ID)
  513. uint32_t l_flags = GE_type_infos[GE_decoded_type(GE_type_infos[a_type].attributes[i - 1]->type_id).id].flags;
  514. return EIF_TEST((l_flags & GE_TYPE_FLAG_EXPANDED) && !(l_flags & GE_TYPE_FLAG_BASIC_MASK));
  515. #else
  516. return EIF_FALSE;
  517. #endif
  518. }
  519. /*
  520. * Get a lock on `GE_mark_object' and `GE_unmark_object' routines so that
  521. * 2 threads cannot `GE_mark_object' and `GE_unmark_object' at the same time.
  522. */
  523. void GE_lock_marking(void)
  524. {
  525. #ifdef GE_USE_THREADS
  526. /* TODO */
  527. #endif
  528. }
  529. /*
  530. * Release a lock on `GE_mark_object' and `GE_unmark_object', so that another
  531. * thread can use `GE_mark_object' and `GE_unmark_object'.
  532. */
  533. void GE_unlock_marking(void)
  534. {
  535. #ifdef GE_USE_THREADS
  536. /* TODO */
  537. #endif
  538. }
  539. /*
  540. * Is `obj' marked?
  541. */
  542. EIF_BOOLEAN GE_is_object_marked(EIF_POINTER obj)
  543. {
  544. return EIF_TEST(((EIF_REFERENCE)obj)->flags & GE_OBJECT_FLAG_MARKED);
  545. }
  546. /*
  547. * Mark `obj'.
  548. */
  549. void GE_mark_object(EIF_POINTER obj)
  550. {
  551. ((EIF_REFERENCE)obj)->flags |= GE_OBJECT_FLAG_MARKED;
  552. }
  553. /*
  554. * Unmark `obj'.
  555. */
  556. void GE_unmark_object(EIF_POINTER obj)
  557. {
  558. ((EIF_REFERENCE)obj)->flags &= ~GE_OBJECT_FLAG_MARKED;
  559. }
  560. /*
  561. * New instance of dynamic `a_type'.
  562. * Note: returned object is not initialized and may
  563. * hence violate its invariant.
  564. * `a_type' cannot represent a SPECIAL type, use
  565. * `GE_new_special_of_reference_instance_of_type_index' instead.
  566. */
  567. EIF_REFERENCE GE_new_instance_of_type_index(EIF_TYPE_INDEX a_type)
  568. {
  569. EIF_REFERENCE (*l_new)(EIF_BOOLEAN);
  570. l_new = (EIF_REFERENCE (*)(EIF_BOOLEAN))GE_type_infos[a_type].new_instance;
  571. if (l_new) {
  572. return l_new(EIF_TRUE);
  573. } else {
  574. return EIF_VOID;
  575. }
  576. }
  577. /*
  578. * New instance of dynamic `a_type' that represents
  579. * a SPECIAL with can contain `a_capacity' elements of reference type.
  580. * To create a SPECIAL of basic type, use class SPECIAL directly.
  581. */
  582. EIF_REFERENCE GE_new_special_of_reference_instance_of_type_index(EIF_TYPE_INDEX a_type, EIF_INTEGER a_capacity)
  583. {
  584. EIF_REFERENCE (*l_new)(EIF_INTEGER,EIF_BOOLEAN);
  585. l_new = (EIF_REFERENCE (*)(EIF_INTEGER,EIF_BOOLEAN))GE_type_infos[a_type].new_instance;
  586. if (l_new) {
  587. return l_new(a_capacity, EIF_TRUE);
  588. } else {
  589. return EIF_VOID;
  590. }
  591. }
  592. /*
  593. * New instance of TYPE for object of type `a_type'.
  594. */
  595. EIF_REFERENCE GE_new_type_instance_of_encoded_type(EIF_ENCODED_TYPE a_type)
  596. {
  597. EIF_TYPE l_decoded_type;
  598. EIF_TYPE_INDEX l_type_index;
  599. EIF_TYPE_INDEX l_annotations;
  600. EIF_REFERENCE l_result;
  601. l_decoded_type = GE_decoded_type(a_type);
  602. l_type_index = l_decoded_type.id;
  603. l_annotations = l_decoded_type.annotations;
  604. l_result = (EIF_REFERENCE)&(GE_types[l_type_index][l_annotations]);
  605. if (l_result->id == 0) {
  606. l_result = EIF_VOID;
  607. GE_raise(GE_EX_PROG);
  608. }
  609. return l_result;
  610. }
  611. #ifdef __cplusplus
  612. }
  613. #endif
  614. #endif