method_id.c 4.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. /* Copyright 2017, 2018, 2019, 2020 Gabriel Czernikier
  2. *
  3. * This file is part of Côtehaus.
  4. * Côtehaus is free software: you can redistribute it and/or modify
  5. * it under the terms of one of the following:
  6. * 1. The same dual license as that of Côtehaus itself, of which individual licenses are
  7. * the MIT License and the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. * 2. The MIT License.
  11. * 3. The GNU General Public License as published by
  12. * the Free Software Foundation, either version 3 of the License, or
  13. * (at your option) any later version.
  14. * Côtehaus is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * MIT License and the GNU General Public License for more details.
  18. * You should have received a copy of the MIT License and the GNU General Public License
  19. * along with Côtehaus. If not, see <https://opensource.org/licenses/MIT> and <http://www.gnu.org/licenses/>.
  20. */
  21. #include<stdbool.h>
  22. #include<stdlib.h>
  23. LIST_HEAD(method_id_head); // struct method_id_st
  24. unsigned long method_id_list_size = 0;
  25. struct method_id_st *add_method_id(struct type_id_st *class_idx, struct proto_id_st *proto_idx, struct str_id_st *name_idx) {
  26. struct method_id_st *method_id = (struct method_id_st*)malloc(sizeof(struct method_id_st));
  27. method_id->class_idx = class_idx;
  28. method_id->proto_idx = proto_idx;
  29. method_id->name_idx = name_idx;
  30. method_id->external = class_idx->cotehaus_class_def->external;
  31. list_add(&method_id->method_id_lst, &method_id_head);
  32. method_id_list_size++;
  33. return method_id;
  34. }
  35. struct omethod_id_st {
  36. struct method_id_st *method_id;
  37. struct omethod_id_st *next_representative;
  38. } *omethod_id_ary;
  39. int omethod_id_st_compar(struct omethod_id_st *omethod_id_1, struct omethod_id_st *omethod_id_2) {
  40. if(oproto_id_1->proto_id->return_type_idx!=oproto_id_2->proto_id->return_type_idx) {
  41. return oproto_id_1->proto_id->return_type_idx-oproto_id_2->proto_id->return_type_idx;
  42. }
  43. if(omethod_id_1->class_idx->idx!=omethod_id_2->class_idx->idx)
  44. return omethod_id_1->class_idx->idx-omethod_id_2->class_idx->idx;
  45. if(omethod_id_1->name_idx->idx!=omethod_id_2->name_idx->idx)
  46. return omethod_id_1->name_idx->idx-omethod_id_2->name_idx->idx;
  47. return omethod_id_1->proto_idx->idx-omethod_id_2->proto_idx->idx;
  48. return 0;
  49. }
  50. void build_omethod_id() {
  51. omethod_id_ary = malloc(method_id_list_size*sizeof(struct omethod_id_st));
  52. memset(omethod_id_ary, 0, method_id_list_size*sizeof(struct omethod_id_st));
  53. struct list_head *tmp;
  54. unsigned int i=0;
  55. list_for_each(tmp, &method_id_head) {
  56. (omethod_id_ary+i)->method_id = (struct method_id_st *)list_entry(tmp, struct method_id_st, method_id_list);
  57. i++;
  58. }
  59. qsort(omethod_id_ary, method_id_list_size, sizeof(struct omethod_id_st), (int (*)(const void *, const void *))omethod_id_st_compar);
  60. i=1;
  61. unsigned int major_i = 0, major_idx = 0;
  62. while(major_i<method_id_list_size) {
  63. (omethod_id_ary+major_i)->method_id->idx = major_idx;
  64. while(i!=method_id_list_size && omethod_id_st_compar(omethod_id_ary+major_i, omethod_id_ary+i)==0) {
  65. (omethod_id_ary+i)->method_id->idx = (omethod_id_ary+major_i)->method_id->idx;
  66. i++;
  67. }
  68. if(i!=method_id_list_size)
  69. (omethod_id_ary+major_i)->next_representative = omethod_id_ary+i;
  70. major_i=i++;
  71. major_idx++;
  72. }
  73. bounds_move(NH_METHOD_ID_IDX, (2*sizeof(uint16_t))+sizeof(uint32_t)/*Storage Designators: ((struct type_id_st)(struct method_id_st).class_idx).idx==uint16_t,
  74. ((struct proto_id_st)(struct method_id_st).proto_idx).idx==uint16_t,
  75. ((struct str_id_st)(struct method_id_st).name_idx).idx==uint32_t,
  76. */ *major_idx);
  77. majors_size_ary[NH_METHOD_ID_IDX] = major_idx;
  78. }
  79. void pack_omethod_id() {
  80. for(struct omethod_id_st *omethod_id_representative = omethod_id_ary;omethod_id_representative!=NULL; omethod_id_representative=omethod_id_representative->next_representative){
  81. // skip items collected during parsing of external refs
  82. if(omethod_id_representative->method_id->external)
  83. continue;
  84. uint16_t packed16 = htole16(omethod_id_representative->method_id->class_idx->idx);
  85. BUFFER_WRITE(buffer[NH_METHOD_ID_IDX],buf_len[NH_METHOD_ID_IDX],&packed16,buf_offset[NH_METHOD_ID_IDX],sizeof(uint16_t))
  86. packed16 = htole16(omethod_id_representative->method_id->proto_idx->idx);
  87. BUFFER_WRITE(buffer[NH_METHOD_ID_IDX],buf_len[NH_METHOD_ID_IDX],&packed16,buf_offset[NH_METHOD_ID_IDX],sizeof(uint16_t))
  88. uint32_t packed = htole32(omethod_id_representative->method_id->name_idx->idx);
  89. BUFFER_WRITE(buffer[NH_METHOD_ID_IDX],buf_len[NH_METHOD_ID_IDX],&packed,buf_offset[NH_METHOD_ID_IDX],sizeof(uint32_t))
  90. }
  91. }