runtime/ffi/ffi_symbol.c - ktap

Functions defined

Source code

  1. /*
  2. * ffi_symbol.c - ktapvm kernel module ffi symbol submodule
  3. *
  4. * This file is part of ktap by Jovi Zhangwei.
  5. *
  6. * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
  7. *
  8. * ktap is free software; you can redistribute it and/or modify it
  9. * under the terms and conditions of the GNU General Public License,
  10. * version 2, as published by the Free Software Foundation.
  11. *
  12. * ktap is distributed in the hope it will be useful, but WITHOUT
  13. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  15. * more details.
  16. *
  17. * You should have received a copy of the GNU General Public License along with
  18. * this program; if not, write to the Free Software Foundation, Inc.,
  19. * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  20. */


  21. #include "../../include/ktap_types.h"
  22. #include "../../include/ktap_ffi.h"
  23. #include "../ktap.h"
  24. #include "../kp_vm.h"
  25. #include "../kp_obj.h"
  26. #include "../kp_str.h"
  27. #include "../kp_tab.h"

  28. static inline csymbol *get_csym_arr(ktap_state_t *ks)
  29. {
  30.     return G(ks)->ffis.csym_arr;
  31. }

  32. static inline int get_csym_nr(ktap_state_t *ks)
  33. {
  34.     return G(ks)->ffis.csym_nr;
  35. }

  36. static inline void set_csym_arr(ktap_state_t *ks, csymbol *csym)
  37. {
  38.     G(ks)->ffis.csym_arr = csym;
  39. }

  40. static inline void set_csym_nr(ktap_state_t *ks, int nr)
  41. {
  42.     G(ks)->ffis.csym_nr = nr;
  43. }


  44. static inline ktap_tab_t *get_ffi_ctable(ktap_state_t *ks)
  45. {
  46.     return G(ks)->ffis.ctable;
  47. }

  48. static int setup_ffi_ctable(ktap_state_t *ks)
  49. {
  50.     ktap_val_t ffi_name, ffi_lib_name, ffi_mt;
  51.     const ktap_val_t *gt, *ffit;
  52.     ktap_tab_t *registry;

  53.     gt = kp_tab_getint(hvalue(&G(ks)->registry), KTAP_RIDX_GLOBALS);

  54.     G(ks)->ffis.ctable = kp_tab_new(ks, 0, 512);
  55.     if (!G(ks)->ffis.ctable)
  56.         return -1;

  57.     /* get global["ffi"] */
  58.     set_string(&ffi_name, kp_str_new(ks, "ffi"));
  59.     registry = hvalue(gt);
  60.     ffit = kp_tab_get(ks, registry, &ffi_name);
  61.     /* insert ffi C table to ffi table */
  62.     set_table(&ffi_mt, get_ffi_ctable(ks));
  63.     set_string(&ffi_lib_name, kp_str_new(ks, "C"));
  64.     registry = hvalue(ffit);
  65.     kp_tab_setvalue(ks, registry, &ffi_lib_name, &ffi_mt);

  66.     return 0;
  67. }

  68. inline csymbol *ffi_get_csym_by_id(ktap_state_t *ks, int id)
  69. {
  70.     return &(get_csym_arr(ks)[id]);
  71. }

  72. csymbol_id ffi_get_csym_id(ktap_state_t *ks, char *name)
  73. {
  74.     int i;

  75.     for (i = 0; i < get_csym_nr(ks); i++) {
  76.         if (!strcmp(name, csym_name(ffi_get_csym_by_id(ks, i)))) {
  77.             return i;
  78.         }
  79.     }

  80.     kp_error(ks, "Cannot find csymbol with name %s\n", name);
  81.     return 0;
  82. }

  83. static void add_ffi_func_to_ctable(ktap_state_t *ks, csymbol_id id)
  84. {
  85.     ktap_val_t func_name, fv;
  86.     ktap_cdata_t *cd;
  87.     csymbol *cs;

  88.     /* push cdata to ctable */
  89.     set_cdata(&fv, kp_obj_newobject(ks, KTAP_TYPE_CDATA, sizeof(ktap_cdata_t),
  90.                     NULL));
  91.     cd = cdvalue(&fv);
  92.     cd_set_csym_id(cd, id);

  93.     cs = id_to_csym(ks, id);
  94.     set_string(&func_name, kp_str_new(ks, csym_name(cs)));
  95.     kp_tab_setvalue(ks, get_ffi_ctable(ks), &func_name, &fv);
  96. }

  97. static int setup_ffi_symbol_table(ktap_state_t *ks)
  98. {
  99.     int i;
  100.     csymbol *cs;

  101.     if (setup_ffi_ctable(ks))
  102.         return -1;

  103.     /* push all functions to ctable */
  104.     for (i = 0; i < get_csym_nr(ks); i++) {
  105.         cs = &get_csym_arr(ks)[i];
  106.         switch (cs->type) {
  107.         case FFI_FUNC:
  108.             kp_verbose_printf(ks, "[%d] loading C function %s\n",
  109.                     i, csym_name(cs));
  110.             add_ffi_func_to_ctable(ks, i);
  111.             kp_verbose_printf(ks, "%s loaded\n", csym_name(cs));
  112.             break;
  113.         case FFI_STRUCT:
  114.         case FFI_UNION:
  115.             break;
  116.         default:
  117.             break;
  118.         }
  119.     }

  120.     return 0;
  121. }

  122. void ffi_free_symbols(ktap_state_t *ks)
  123. {
  124.     int i;
  125.     csymbol_id *arg_ids;
  126.     csymbol *cs;

  127.     if (!get_csym_arr(ks))
  128.         return;

  129.     for (i = 0; i < get_csym_nr(ks); i++) {
  130.         cs = &get_csym_arr(ks)[i];
  131.         switch (csym_type(cs)) {
  132.         case FFI_FUNC:
  133.             arg_ids = csym_func_arg_ids(cs);
  134.             if (arg_ids)
  135.                 kp_free(ks, arg_ids);
  136.             break;
  137.         case FFI_STRUCT:
  138.         case FFI_UNION:
  139.             /*@TODO finish this  20.11 2013 (houqp)*/
  140.             break;
  141.         default:
  142.             break;
  143.         }
  144.     }

  145.     kp_free(ks, get_csym_arr(ks));
  146. }

  147. int ffi_set_csym_arr(ktap_state_t *ks, int cs_nr, csymbol *new_arr)
  148. {
  149.     set_csym_nr(ks, cs_nr);
  150.     set_csym_arr(ks, new_arr);
  151.     return setup_ffi_symbol_table(ks);
  152. }