finsh_vm.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2010-03-22 Bernard first version
  9. */
  10. #include <finsh.h>
  11. #include "finsh_vm.h"
  12. #include "finsh_ops.h"
  13. #include "finsh_var.h"
  14. /* stack */
  15. union finsh_value finsh_vm_stack[FINSH_STACK_MAX];
  16. /* text segment */
  17. uint8_t text_segment[FINSH_TEXT_MAX];
  18. union finsh_value* finsh_sp; /* stack pointer */
  19. uint8_t* finsh_pc; /* PC */
  20. /* syscall list, for dynamic system call register */
  21. struct finsh_syscall_item* global_syscall_list = NULL;
  22. // #define FINSH_VM_DISASSEMBLE
  23. void finsh_vm_run()
  24. {
  25. uint8_t op;
  26. /* if you want to disassemble the byte code, please define FINSH_VM_DISASSEMBLE */
  27. #ifdef FINSH_VM_DISASSEMBLE
  28. void finsh_disassemble();
  29. finsh_disassemble();
  30. #endif
  31. /* set sp(stack pointer) to the beginning of stack */
  32. finsh_sp = &finsh_vm_stack[0];
  33. /* set pc to the beginning of text segment */
  34. finsh_pc = &text_segment[0];
  35. while ((finsh_pc - &text_segment[0] >= 0) &&
  36. (finsh_pc - &text_segment[0] < FINSH_TEXT_MAX))
  37. {
  38. /* get op */
  39. op = *finsh_pc++;
  40. /* call op function */
  41. op_table[op]();
  42. }
  43. }
  44. #ifdef RT_USING_HEAP
  45. void finsh_syscall_append(const char* name, syscall_func func)
  46. {
  47. /* create the syscall */
  48. struct finsh_syscall_item* item;
  49. item = (struct finsh_syscall_item*)rt_malloc(sizeof(struct finsh_syscall_item));
  50. if (item != RT_NULL)
  51. {
  52. item->next = NULL;
  53. item->syscall.name = rt_strdup(name);
  54. item->syscall.func = func;
  55. if (global_syscall_list == NULL)
  56. {
  57. global_syscall_list = item;
  58. }
  59. else
  60. {
  61. item->next = global_syscall_list;
  62. global_syscall_list = item;
  63. }
  64. }
  65. }
  66. #endif
  67. #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
  68. struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
  69. {
  70. unsigned int *ptr;
  71. ptr = (unsigned int*) (call + 1);
  72. while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
  73. ptr ++;
  74. return (struct finsh_syscall*)ptr;
  75. }
  76. struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
  77. {
  78. unsigned int *ptr;
  79. ptr = (unsigned int*) (call + 1);
  80. while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
  81. ptr ++;
  82. return (struct finsh_sysvar*)ptr;
  83. }
  84. #endif
  85. struct finsh_syscall* finsh_syscall_lookup(const char* name)
  86. {
  87. struct finsh_syscall* index;
  88. struct finsh_syscall_item* item;
  89. for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
  90. {
  91. if (strcmp(index->name, name) == 0)
  92. return index;
  93. }
  94. /* find on syscall list */
  95. item = global_syscall_list;
  96. while (item != NULL)
  97. {
  98. if (strncmp(item->syscall.name, name, strlen(name)) == 0)
  99. {
  100. return &(item->syscall);
  101. }
  102. item = item->next;
  103. }
  104. return NULL;
  105. }
  106. #ifdef FINSH_VM_DISASSEMBLE
  107. void finsh_disassemble()
  108. {
  109. uint8_t *pc, op;
  110. pc = &text_segment[0];
  111. while (*pc != 0)
  112. {
  113. op = *pc;
  114. switch (op)
  115. {
  116. case FINSH_OP_ADD_BYTE:
  117. pc ++;
  118. rt_kprintf("addb\n");
  119. break;
  120. case FINSH_OP_SUB_BYTE:
  121. pc ++;
  122. rt_kprintf("subb\n");
  123. break;
  124. case FINSH_OP_DIV_BYTE:
  125. pc ++;
  126. rt_kprintf("divb\n");
  127. break;
  128. case FINSH_OP_MOD_BYTE:
  129. pc ++;
  130. rt_kprintf("modb\n");
  131. break;
  132. case FINSH_OP_MUL_BYTE:
  133. pc ++;
  134. rt_kprintf("mulb\n");
  135. break;
  136. case FINSH_OP_AND_BYTE:
  137. pc ++;
  138. rt_kprintf("andb\n");
  139. break;
  140. case FINSH_OP_OR_BYTE:
  141. pc ++;
  142. rt_kprintf("orb\n");
  143. break;
  144. case FINSH_OP_XOR_BYTE:
  145. pc ++;
  146. rt_kprintf("xorb\n");
  147. break;
  148. case FINSH_OP_BITWISE_BYTE:
  149. pc ++;
  150. rt_kprintf("bwb\n");
  151. break;
  152. case FINSH_OP_SHL_BYTE:
  153. pc ++;
  154. rt_kprintf("shlb\n");
  155. break;
  156. case FINSH_OP_SHR_BYTE:
  157. pc ++;
  158. rt_kprintf("shrb\n");
  159. break;
  160. case FINSH_OP_LD_BYTE:
  161. pc ++;
  162. rt_kprintf("ldb %d\n", *pc++);
  163. break;
  164. case FINSH_OP_LD_VALUE_BYTE:
  165. pc ++;
  166. rt_kprintf("ldb [0x%x]\n", FINSH_GET32(pc));
  167. pc += 4;
  168. break;
  169. case FINSH_OP_ST_BYTE:
  170. pc ++;
  171. rt_kprintf("stb\n");
  172. break;
  173. case FINSH_OP_ADD_WORD:
  174. pc ++;
  175. rt_kprintf("addw\n");
  176. break;
  177. case FINSH_OP_SUB_WORD:
  178. pc ++;
  179. rt_kprintf("subw\n");
  180. break;
  181. case FINSH_OP_DIV_WORD:
  182. pc ++;
  183. rt_kprintf("divw\n");
  184. break;
  185. case FINSH_OP_MOD_WORD:
  186. pc ++;
  187. rt_kprintf("modw\n");
  188. break;
  189. case FINSH_OP_MUL_WORD:
  190. pc ++;
  191. rt_kprintf("mulw\n");
  192. break;
  193. case FINSH_OP_AND_WORD:
  194. pc ++;
  195. rt_kprintf("andw\n");
  196. break;
  197. case FINSH_OP_OR_WORD:
  198. pc ++;
  199. rt_kprintf("orw\n");
  200. break;
  201. case FINSH_OP_XOR_WORD:
  202. pc ++;
  203. rt_kprintf("xorw\n");
  204. break;
  205. case FINSH_OP_BITWISE_WORD:
  206. pc ++;
  207. rt_kprintf("bww\n");
  208. break;
  209. case FINSH_OP_SHL_WORD:
  210. pc ++;
  211. rt_kprintf("shlw\n");
  212. break;
  213. case FINSH_OP_SHR_WORD:
  214. pc ++;
  215. rt_kprintf("shrw\n");
  216. break;
  217. case FINSH_OP_LD_WORD:
  218. pc ++;
  219. rt_kprintf("ldw %d\n", FINSH_GET16(pc));
  220. pc += 2;
  221. break;
  222. case FINSH_OP_LD_VALUE_WORD:
  223. pc ++;
  224. rt_kprintf("ldw [0x%x]\n", FINSH_GET32(pc));
  225. pc += 4;
  226. break;
  227. case FINSH_OP_ST_WORD:
  228. pc ++;
  229. rt_kprintf("stw\n");
  230. break;
  231. case FINSH_OP_ADD_DWORD:
  232. pc ++;
  233. rt_kprintf("addd\n");
  234. break;
  235. case FINSH_OP_SUB_DWORD:
  236. pc ++;
  237. rt_kprintf("subd\n");
  238. break;
  239. case FINSH_OP_DIV_DWORD:
  240. pc ++;
  241. rt_kprintf("divd\n");
  242. break;
  243. case FINSH_OP_MOD_DWORD:
  244. pc ++;
  245. rt_kprintf("modd\n");
  246. break;
  247. case FINSH_OP_MUL_DWORD:
  248. pc ++;
  249. rt_kprintf("muld\n");
  250. break;
  251. case FINSH_OP_AND_DWORD:
  252. pc ++;
  253. rt_kprintf("andd\n");
  254. break;
  255. case FINSH_OP_OR_DWORD:
  256. pc ++;
  257. rt_kprintf("ord\n");
  258. break;
  259. case FINSH_OP_XOR_DWORD:
  260. pc ++;
  261. rt_kprintf("xord\n");
  262. break;
  263. case FINSH_OP_BITWISE_DWORD:
  264. pc ++;
  265. rt_kprintf("bwd\n");
  266. break;
  267. case FINSH_OP_SHL_DWORD:
  268. pc ++;
  269. rt_kprintf("shld\n");
  270. break;
  271. case FINSH_OP_SHR_DWORD:
  272. pc ++;
  273. rt_kprintf("shrd\n");
  274. break;
  275. case FINSH_OP_LD_DWORD:
  276. pc ++;
  277. rt_kprintf("ldd 0x%x\n", FINSH_GET32(pc));
  278. pc += 4;
  279. break;
  280. case FINSH_OP_LD_VALUE_DWORD:
  281. pc ++;
  282. rt_kprintf("ldd [0x%x]\n", FINSH_GET32(pc));
  283. pc += 4;
  284. break;
  285. case FINSH_OP_ST_DWORD:
  286. pc ++;
  287. rt_kprintf("std\n");
  288. break;
  289. case FINSH_OP_POP:
  290. rt_kprintf("pop\n");
  291. pc ++;
  292. break;
  293. case FINSH_OP_SYSCALL:
  294. pc ++;
  295. rt_kprintf("syscall %d\n", *pc++);
  296. break;
  297. case FINSH_OP_LD_VALUE_BYTE_STACK:
  298. pc ++;
  299. rt_kprintf("ldb [sp]\n");
  300. break;
  301. case FINSH_OP_LD_VALUE_WORD_STACK:
  302. pc ++;
  303. rt_kprintf("ldw [sp]\n");
  304. break;
  305. case FINSH_OP_LD_VALUE_DWORD_STACK:
  306. pc ++;
  307. rt_kprintf("ldd [sp]\n");
  308. break;
  309. default:
  310. return;
  311. }
  312. }
  313. }
  314. #endif