Guest User

Untitled

a guest
Nov 16th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 44.15 KB | None | 0 0
  1. #define _BSD_SOURCE
  2. #include <sys/mman.h>
  3. #include <sys/stat.h>
  4. #include <sys/types.h>
  5. #include <stdlib.h>
  6. #include <stdint.h>
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <time.h>
  12. #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
  13. #define MAP_ANONYMOUS MAP_ANON
  14. #endif
  15. #include <stddef.h>
  16. #include <stdarg.h>
  17. #ifndef Dst_DECL
  18. #define Dst_DECL dasm_State **Dst
  19. #endif
  20. #ifndef Dst_REF
  21. #define Dst_REF (*Dst)
  22. #endif
  23. #ifndef DASM_FDEF
  24. #define DASM_FDEF extern
  25. #endif
  26. #ifndef DASM_M_GROW
  27. #define DASM_M_GROW(ctx, t, p, sz, need)
  28. do {
  29. size_t _sz = (sz), _need = (need);
  30. if (_sz < _need) {
  31. if (_sz < 16) _sz = 16;
  32. while (_sz < _need) _sz += _sz;
  33. (p) = (t *)realloc((p), _sz);
  34. if ((p) == NULL) exit(1);
  35. (sz) = _sz;
  36. }
  37. } while(0)
  38. #endif
  39. #ifndef DASM_M_FREE
  40. #define DASM_M_FREE(ctx, p, sz) free(p)
  41. #endif
  42. /* Maximum number of section buffer positions for a single dasm_put() call. */
  43. #define DASM_MAXSECPOS 25
  44.  
  45. /* DynASM encoder status codes. Action list offset or number are or'ed in. */
  46. #define DASM_S_OK 0x00000000
  47. #define DASM_S_NOMEM 0x01000000
  48. #define DASM_S_PHASE 0x02000000
  49. #define DASM_S_MATCH_SEC 0x03000000
  50. #define DASM_S_RANGE_I 0x11000000
  51. #define DASM_S_RANGE_SEC 0x12000000
  52. #define DASM_S_RANGE_LG 0x13000000
  53. #define DASM_S_RANGE_PC 0x14000000
  54. #define DASM_S_RANGE_VREG 0x15000000
  55. #define DASM_S_UNDEF_L 0x21000000
  56. #define DASM_S_UNDEF_PC 0x22000000
  57.  
  58. /* Macros to convert positions (8 bit section + 24 bit index). */
  59. #define DASM_POS2IDX(pos) ((pos)&0x00ffffff)
  60. #define DASM_POS2BIAS(pos) ((pos)&0xff000000)
  61. #define DASM_SEC2POS(sec) ((sec)<<24)
  62. #define DASM_POS2SEC(pos) ((pos)>>24)
  63. #define DASM_POS2PTR(D, pos) (D->sections[DASM_POS2SEC(pos)].rbuf + (pos))
  64. typedef struct dasm_State dasm_State;
  65. DASM_FDEF void dasm_init(Dst_DECL, int maxsection);
  66. DASM_FDEF void dasm_free(Dst_DECL);
  67. DASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);
  68. DASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);
  69. DASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);
  70. DASM_FDEF void dasm_put(Dst_DECL, int start, ...);
  71. DASM_FDEF int dasm_link(Dst_DECL, size_t *szp);
  72. DASM_FDEF int dasm_encode(Dst_DECL, void *buffer);
  73. DASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);
  74. #ifdef DASM_CHECKS
  75. DASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);
  76. #else
  77. #define dasm_checkstep(a, b) 0
  78. #endif
  79.  
  80.  
  81. #define DASM_ARCH "x86"
  82.  
  83. #ifndef DASM_EXTERN
  84. #define DASM_EXTERN(a,b,c,d) 0
  85. #endif
  86.  
  87. /* Action definitions. DASM_STOP must be 255. */
  88. enum {
  89. DASM_DISP = 233,
  90. DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,
  91. DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,
  92. DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,
  93. DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP
  94. };
  95.  
  96. /* Action list type. */
  97. typedef const unsigned char * dasm_ActList;
  98.  
  99. /* Per-section structure. */
  100. typedef struct dasm_Section {
  101. int * rbuf; /* Biased buffer pointer (negative section bias). */
  102. int * buf; /* True buffer pointer. */
  103. size_t bsize; /* Buffer size in bytes. */
  104. int pos; /* Biased buffer position. */
  105. int epos; /* End of biased buffer position - max single put. */
  106. int ofs; /* Byte offset into section. */
  107. } dasm_Section;
  108.  
  109. /* Core structure holding the DynASM encoding state. */
  110. struct dasm_State {
  111. size_t psize; /* Allocated size of this structure. */
  112. dasm_ActList actionlist; /* Current actionlist pointer. */
  113. int * lglabels; /* Local/global chain/pos ptrs. */
  114. size_t lgsize;
  115. int * pclabels; /* PC label chains/pos ptrs. */
  116. size_t pcsize;
  117. void ** globals; /* Array of globals (bias -10). */
  118. dasm_Section * section; /* Pointer to active section. */
  119. size_t codesize; /* Total size of all code sections. */
  120. int maxsection; /* 0 <= sectionidx < maxsection. */
  121. int status; /* Status code. */
  122. dasm_Section sections[1]; /* All sections. Alloc-extended. */
  123. };
  124.  
  125. /* The size of the core structure depends on the max. number of sections. */
  126. #define DASM_PSZ(ms) (sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))
  127.  
  128.  
  129. /* Initialize DynASM state. */
  130. void dasm_init(Dst_DECL, int maxsection) {
  131. dasm_State * D;
  132. size_t psz = 0;
  133. int i;
  134. Dst_REF = NULL;
  135. DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));
  136. D = Dst_REF;
  137. D->psize = psz;
  138. D->lglabels = NULL;
  139. D->lgsize = 0;
  140. D->pclabels = NULL;
  141. D->pcsize = 0;
  142. D->globals = NULL;
  143. D->maxsection = maxsection;
  144. for (i = 0; i < maxsection; i++) {
  145. D->sections[i].buf = NULL; /* Need this for pass3. */
  146. D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);
  147. D->sections[i].bsize = 0;
  148. D->sections[i].epos = 0; /* Wrong, but is recalculated after resize. */
  149. }
  150. }
  151.  
  152. /* Free DynASM state. */
  153. void dasm_free(Dst_DECL) {
  154. dasm_State * D = Dst_REF;
  155. int i;
  156. for (i = 0; i < D->maxsection; i++)
  157. if (D->sections[i].buf)
  158. DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);
  159. if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);
  160. if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);
  161. DASM_M_FREE(Dst, D, D->psize);
  162. }
  163.  
  164. /* Setup global label array. Must be called before dasm_setup(). */
  165. void dasm_setupglobal(Dst_DECL, void ** gl, unsigned int maxgl) {
  166. dasm_State * D = Dst_REF;
  167. D->globals = gl - 10; /* Negative bias to compensate for locals. */
  168. DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));
  169. }
  170.  
  171. /* Grow PC label array. Can be called after dasm_setup(), too. */
  172. void dasm_growpc(Dst_DECL, unsigned int maxpc) {
  173. dasm_State * D = Dst_REF;
  174. size_t osz = D->pcsize;
  175. DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));
  176. memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);
  177. }
  178.  
  179. /* Setup encoder. */
  180. void dasm_setup(Dst_DECL, const void * actionlist) {
  181. dasm_State * D = Dst_REF;
  182. int i;
  183. D->actionlist = (dasm_ActList)actionlist;
  184. D->status = DASM_S_OK;
  185. D->section = &D->sections[0];
  186. memset((void *)D->lglabels, 0, D->lgsize);
  187. if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);
  188. for (i = 0; i < D->maxsection; i++) {
  189. D->sections[i].pos = DASM_SEC2POS(i);
  190. D->sections[i].ofs = 0;
  191. }
  192. }
  193.  
  194.  
  195. #ifdef DASM_CHECKS
  196. #define CK(x, st)
  197. do { if (!(x)) {
  198. D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)
  199. #define CKPL(kind, st)
  200. do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) {
  201. D->status=DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)
  202. #else
  203. #define CK(x, st) ((void)0)
  204. #define CKPL(kind, st) ((void)0)
  205. #endif
  206.  
  207. /* Pass 1: Store actions and args, link branches/labels, estimate offsets. */
  208. void dasm_put(Dst_DECL, int start, ...) {
  209. va_list ap;
  210. dasm_State * D = Dst_REF;
  211. dasm_ActList p = D->actionlist + start;
  212. dasm_Section * sec = D->section;
  213. int pos = sec->pos, ofs = sec->ofs, mrm = 4;
  214. int * b;
  215. if (pos >= sec->epos) {
  216. DASM_M_GROW(Dst, int, sec->buf, sec->bsize,
  217. sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));
  218. sec->rbuf = sec->buf - DASM_POS2BIAS(pos);
  219. sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);
  220. }
  221. b = sec->rbuf;
  222. b[pos++] = start;
  223. va_start(ap, start);
  224. while (1) {
  225. int action = *p++;
  226. if (action < DASM_DISP)
  227. ofs++;
  228.  
  229. else if (action <= DASM_REL_A) {
  230. int n = va_arg(ap, int);
  231. b[pos++] = n;
  232. switch (action) {
  233. case DASM_DISP:
  234. if (n == 0) { if ((mrm&7) == 4) mrm = p[-2]; if ((mrm&7) != 5) break; }
  235. case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob;
  236. case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */
  237. case DASM_IMM_D: ofs += 4; break;
  238. case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;
  239. case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;
  240. case DASM_VREG: CK((n&-8) == 0 && (n != 4 || (*p&1) == 0), RANGE_VREG);
  241. }
  242. mrm = 4;
  243. } else {
  244. int * pl, n;
  245. switch (action) {
  246. case DASM_REL_LG:
  247. case DASM_IMM_LG:
  248. n = *p++; pl = D->lglabels + n;
  249. /* Bkwd rel or global. */
  250. if (n <= 246) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }
  251. pl -= 246; n = *pl;
  252. if (n < 0) n = 0; /* Start new chain for fwd rel if label exists. */
  253. goto linkrel;
  254. case DASM_REL_PC:
  255. case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
  256. putrel:
  257. n = *pl;
  258. if (n < 0) /* Label exists. Get label pos and store it. */
  259. b[pos] = -n;
  260.  
  261. else {
  262. linkrel:
  263. b[pos] = n; /* Else link to rel chain, anchored at label. */
  264. *pl = pos;
  265. }
  266. pos++;
  267. ofs += 4; /* Maximum offset needed. */
  268. if (action == DASM_REL_LG || action == DASM_REL_PC)
  269. b[pos++] = ofs; /* Store pass1 offset estimate. */
  270. break;
  271. case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;
  272. case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);
  273. putlabel:
  274. n = *pl; /* n > 0: Collapse rel chain and replace with label pos. */
  275. while (n > 0) { int * pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }
  276. *pl = -pos; /* Label exists now. */
  277. b[pos++] = ofs; /* Store pass1 offset estimate. */
  278. break;
  279. case DASM_ALIGN:
  280. case DASM_ESC: p++; ofs++; break;
  281. case DASM_MARK: mrm = p[-2]; break;
  282. case DASM_SECTION:
  283. case DASM_STOP: goto stop;
  284. }
  285. }
  286. }
  287. stop:
  288. va_end(ap);
  289. sec->pos = pos;
  290. sec->ofs = ofs;
  291. }
  292. #undef CK
  293.  
  294. /* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */
  295. int dasm_link(Dst_DECL, size_t * szp) {
  296. dasm_State * D = Dst_REF;
  297. int secnum;
  298. int ofs = 0;
  299. #ifdef DASM_CHECKS
  300. *szp = 0;
  301. if (D->status != DASM_S_OK) return D->status;
  302. {
  303. int pc;
  304. for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)
  305. if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;
  306. }
  307. #endif
  308. {
  309. /* Handle globals not defined in this translation unit. */
  310. int idx;
  311. for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {
  312. int n = D->lglabels[idx];
  313. /* Undefined label: Collapse rel chain and replace with marker (< 0). */
  314. while (n > 0) { int * pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }
  315. }
  316. }
  317. /* Combine all code sections. No support for data sections (yet). */
  318. for (secnum = 0; secnum < D->maxsection; secnum++) {
  319. dasm_Section * sec = D->sections + secnum;
  320. int * b = sec->rbuf;
  321. int pos = DASM_SEC2POS(secnum);
  322. int lastpos = sec->pos;
  323. while (pos != lastpos) {
  324. dasm_ActList p = D->actionlist + b[pos++];
  325. while (1) {
  326. int op, action = *p++;
  327. switch (action) {
  328. case DASM_REL_LG: p++; op = p[-3]; goto rel_pc;
  329. case DASM_REL_PC: op = p[-2]; rel_pc: {
  330. int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);
  331. if (shrink) { /* Shrinkable branch opcode? */
  332. int lofs, lpos = b[pos];
  333. if (lpos < 0) goto noshrink; /* Ext global? */
  334. lofs = *DASM_POS2PTR(D, lpos);
  335. if (lpos > pos) { /* Fwd label: add cumulative section offsets. */
  336. int i;
  337. for (i = secnum; i < DASM_POS2SEC(lpos); i++)
  338. lofs += D->sections[i].ofs;
  339. } else {
  340. lofs -= ofs; /* Bkwd label: unfix offset. */
  341. }
  342. lofs -= b[pos+1]; /* Short branch ok? */
  343. if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink; /* Yes. */
  344. else noshrink: shrink = 0; /* No, cannot shrink op. */
  345. }
  346. b[pos+1] = shrink;
  347. pos += 2;
  348. break;
  349. }
  350. case DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;
  351. case DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:
  352. case DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:
  353. case DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;
  354. case DASM_LABEL_LG: p++;
  355. case DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */
  356. case DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */
  357. case DASM_EXTERN: p += 2; break;
  358. case DASM_ESC: p++; break;
  359. case DASM_MARK: break;
  360. case DASM_SECTION: case DASM_STOP: goto stop;
  361. }
  362. }
  363. stop: (void)0;
  364. }
  365. ofs += sec->ofs; /* Next section starts right after current section. */
  366. }
  367. D->codesize = ofs; /* Total size of all code sections */
  368. *szp = ofs;
  369. return DASM_S_OK;
  370. }
  371.  
  372. #define dasmb(x) *cp++ = (unsigned char)(x)
  373. #ifndef DASM_ALIGNED_WRITES
  374. #define dasmw(x)
  375. do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)
  376. #define dasmd(x)
  377. do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)
  378. #else
  379. #define dasmw(x) do { dasmb(x); dasmb((x)>>8); } while (0)
  380. #define dasmd(x) do { dasmw(x); dasmw((x)>>16); } while (0)
  381. #endif
  382.  
  383. /* Pass 3: Encode sections. */
  384. int dasm_encode(Dst_DECL, void * buffer) {
  385. dasm_State * D = Dst_REF;
  386. unsigned char * base = (unsigned char *)buffer;
  387. unsigned char * cp = base;
  388. int secnum;
  389. /* Encode all code sections. No support for data sections (yet). */
  390. for (secnum = 0; secnum < D->maxsection; secnum++) {
  391. dasm_Section * sec = D->sections + secnum;
  392. int * b = sec->buf;
  393. int * endb = sec->rbuf + sec->pos;
  394. while (b != endb) {
  395. dasm_ActList p = D->actionlist + *b++;
  396. unsigned char * mark = NULL;
  397. while (1) {
  398. int action = *p++;
  399. int n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;
  400. switch (action) {
  401. case DASM_DISP: if (!mark) mark = cp; {
  402. unsigned char * mm = mark;
  403. if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;
  404. if (n == 0) {
  405. int mrm = mm[-1]&7;
  406. if (mrm == 4) mrm = mm[0]&7;
  407. if (mrm != 5) { mm[-1] -= 0x80; break; }
  408. }
  409. if (((n+128) & -256) != 0) goto wd;
  410. else mm[-1] -= 0x40;
  411. }
  412. case DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;
  413. case DASM_IMM_DB: if (((n+128)&-256) == 0) {
  414. db:
  415. if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;
  416. } else mark = NULL;
  417. case DASM_IMM_D: wd: dasmd(n); break;
  418. case DASM_IMM_WB: if (((n+128)&-256) == 0) goto db;
  419. else mark = NULL;
  420. case DASM_IMM_W: dasmw(n); break;
  421. case DASM_VREG: { int t = *p++; if (t >= 2) n<<=3; cp[-1] |= n; break; }
  422. case DASM_REL_LG: p++;
  423. if (n >= 0) goto rel_pc;
  424. b++; n = (int)(ptrdiff_t)D->globals[-n];
  425. case DASM_REL_A: rel_a: n -= (int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */
  426. case DASM_REL_PC: rel_pc: {
  427. int shrink = *b++;
  428. int * pb = DASM_POS2PTR(D, n);
  429. if (*pb < 0) { n = pb[1]; goto rel_a; }
  430. n = *pb - ((int)(cp-base) + 4-shrink);
  431. if (shrink == 0) goto wd;
  432. if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;
  433. goto wb;
  434. }
  435. case DASM_IMM_LG:
  436. p++;
  437. if (n < 0) { n = (int)(ptrdiff_t)D->globals[-n]; goto wd; }
  438. case DASM_IMM_PC: {
  439. int * pb = DASM_POS2PTR(D, n);
  440. n = *pb < 0 ? pb[1] : (*pb + (int)(ptrdiff_t)base);
  441. goto wd;
  442. }
  443. case DASM_LABEL_LG: {
  444. int idx = *p++;
  445. if (idx >= 10)
  446. D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));
  447. break;
  448. }
  449. case DASM_LABEL_PC: case DASM_SETLABEL: break;
  450. case DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }
  451. case DASM_ALIGN:
  452. n = *p++;
  453. while (((cp-base) & n)) *cp++ = 0x90; /* nop */
  454. break;
  455. case DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;
  456. case DASM_MARK: mark = cp; break;
  457. case DASM_ESC: action = *p++;
  458. default: *cp++ = action; break;
  459. case DASM_SECTION: case DASM_STOP: goto stop;
  460. }
  461. }
  462. stop: (void)0;
  463. }
  464. }
  465. if (base + D->codesize != cp) /* Check for phase errors. */
  466. return DASM_S_PHASE;
  467. return DASM_S_OK;
  468. }
  469.  
  470. int dasm_getpclabel(Dst_DECL, unsigned int pc) {
  471. dasm_State * D = Dst_REF;
  472. if (pc*sizeof(int) < D->pcsize) {
  473. int pos = D->pclabels[pc];
  474. if (pos < 0) return *DASM_POS2PTR(D, -pos);
  475. if (pos > 0) return -1; /* Undefined. */
  476. }
  477. return -2; /* Unused or out of range. */
  478. }
  479.  
  480. #ifdef DASM_CHECKS
  481. /* Optional sanity checker to call between isolated encoding steps. */
  482. int dasm_checkstep(Dst_DECL, int secmatch) {
  483. dasm_State * D = Dst_REF;
  484. if (D->status == DASM_S_OK) {
  485. int i;
  486. for (i = 1; i <= 9; i++) {
  487. if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }
  488. D->lglabels[i] = 0;
  489. }
  490. }
  491. if (D->status == DASM_S_OK && secmatch >= 0 &&
  492. D->section != &D->sections[secmatch])
  493. D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);
  494. return D->status;
  495. }
  496. #endif
  497.  
  498. extern void * jit_buf;
  499. extern size_t jit_sz;
  500. extern int npc;
  501.  
  502. enum { IN_GLOBAL = 0, IN_FUNC };
  503. enum { BLOCK_LOOP = 1, BLOCK_FUNC };
  504. enum { V_LOCAL, V_GLOBAL };
  505. enum { T_INT, T_STRING, T_DOUBLE };
  506.  
  507. typedef struct {
  508. int address, args, espBgn;
  509. char name[0xFF];
  510. } func_t;
  511.  
  512. typedef struct {
  513. char name[32];
  514. unsigned int id;
  515. int type;
  516. int loctype;
  517. } var_t;
  518.  
  519. typedef struct {
  520. char val[128];
  521. int nline;
  522. } token_t;
  523.  
  524. struct {
  525. token_t * tok_t;
  526. int size, pos;
  527. } tok_t;
  528.  
  529. struct {
  530. unsigned int * addr;
  531. int count;
  532. } brks_t, rets_t;
  533.  
  534. int error(char *, ...);
  535. int lex(char *);
  536. int32_t skip(char * s);
  537. void asmexpr();
  538. int isassign();
  539. int assignment();
  540. int expression(int, int);
  541. int (*parser())(int *, void **);
  542. char * getstr();
  543. func_t * getfn(char *);
  544. var_t * getvar(char *);
  545. void cmpexpr();
  546. static unsigned int w;
  547.  
  548. struct {
  549. uint32_t addr[0xff];
  550. int count;
  551. } memory;
  552.  
  553. static void setxor() {
  554. w = 1234 + (getpid() ^ 0xFFBA9285);
  555. }
  556.  
  557. void init() {
  558. tok_t.pos = 0;
  559. tok_t.size = 0xfff;
  560. setxor();
  561. tok_t.tok_t = calloc(sizeof(token_t), tok_t.size);
  562. brks_t.addr = calloc(sizeof(uint32_t), 1);
  563. rets_t.addr = calloc(sizeof(uint32_t), 1);
  564. }
  565.  
  566. static void freeadd() {
  567. if (memory.count > 0) {
  568. for (--memory.count; memory.count >= 0; --memory.count)
  569. free((void *)memory.addr[memory.count]);
  570. memory.count = 0;
  571. }
  572. }
  573.  
  574. void dispose() {
  575. munmap(jit_buf, jit_sz);
  576. free(brks_t.addr);
  577. free(rets_t.addr);
  578. free(tok_t.tok_t);
  579. freeadd();
  580. }
  581.  
  582. static void put_i32(int32_t n) {
  583. printf("%d", n);
  584. }
  585.  
  586. static void put_str(int32_t * n) {
  587. printf("%s", (char *) n);
  588. }
  589.  
  590. static void put_ln() {
  591. printf("n");
  592. }
  593.  
  594. static void add_mem(int32_t addr) {
  595. memory.addr[memory.count++] = addr;
  596. }
  597.  
  598. static int xor128() {
  599. static uint32_t x = 123456789, y = 362436069, z = 521288629;
  600. uint32_t t;
  601. t = x ^ (x << 11);
  602. x = y; y = z; z = w;
  603. w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
  604. return ((int32_t) w < 0) ? -(int32_t) w : (int32_t) w;
  605. }
  606.  
  607. static void * funcTable[] = {
  608. put_i32, /* 0 */ put_str, /* 4 */ put_ln, /* 8 */ malloc, /* 12 */
  609. xor128, /* 16 */ printf, /* 20 */ add_mem, /* 24 */ usleep, /* 28 */
  610. read, /* 32 */ fprintf, /* 36 */ write, /* 40 */ fgets, /* 44 */
  611. free, /* 48 */ freeadd, /* 52 */ exit, /* 56 */ abort, /* 60 */
  612. close /* 72 */
  613. };
  614.  
  615. int32_t lex(char * code) {
  616. int32_t codeSize = strlen(code), line = 1, i = 0;
  617. int is_crlf = 0;
  618. for (; i < codeSize; i++) {
  619. if (tok_t.size <= i)
  620. tok_t.tok_t = realloc(tok_t.tok_t, (tok_t.size += 512 * sizeof(token_t)));
  621. if (isdigit(code[i])) {
  622. for (; isdigit(code[i]); i++)
  623. strncat(tok_t.tok_t[tok_t.pos].val, &(code[i]), 1);
  624. tok_t.tok_t[tok_t.pos].nline = line;
  625. i--;
  626. tok_t.pos++;
  627. } else if (isalpha(code[i])) {
  628. char * str = tok_t.tok_t[tok_t.pos].val;
  629. for (; isalpha(code[i]) || isdigit(code[i]) || code[i] == '_'; i++)
  630. *str++ = code[i];
  631. tok_t.tok_t[tok_t.pos].nline = line;
  632. i--;
  633. tok_t.pos++;
  634. } else if (code[i] == ' ' || code[i] == 't') {
  635. } else if (code[i] == '#') {
  636. for (i++; code[i] != 'n'; i++) line++;
  637. } else if (code[i] == '"') {
  638. strcpy(tok_t.tok_t[tok_t.pos].val, """);
  639. tok_t.tok_t[tok_t.pos++].nline = line;
  640. for (i++; code[i] != '"' && code[i] != ''; i++)
  641. strncat(tok_t.tok_t[tok_t.pos].val, &(code[i]), 1);
  642. tok_t.tok_t[tok_t.pos].nline = line;
  643. if (code[i] == '')
  644. error("%d: expected expression '"'", tok_t.tok_t[tok_t.pos].nline);
  645. tok_t.pos++;
  646. } else if (code[i] == 'n' || (is_crlf = (code[i] == 'r' && code[i + 1] == 'n'))) {
  647. i += is_crlf;
  648. strcpy(tok_t.tok_t[tok_t.pos].val, ";");
  649. tok_t.tok_t[tok_t.pos].nline = line++;
  650. tok_t.pos++;
  651. } else {
  652. strncat(tok_t.tok_t[tok_t.pos].val, &(code[i]), 1);
  653. if (code[i + 1] == '=' || (code[i] == '+' && code[i + 1] == '+') || (code[i] == '-' && code[i + 1] == '-'))
  654. strncat(tok_t.tok_t[tok_t.pos].val, &(code[++i]), 1);
  655. tok_t.tok_t[tok_t.pos].nline = line;
  656. tok_t.pos++;
  657. }
  658. }
  659. tok_t.tok_t[tok_t.pos].nline = line;
  660. tok_t.size = tok_t.pos - 1;
  661. return 0;
  662. }
  663.  
  664. static int execute(char * source) {
  665. int (*jit_main)(int *, void **);
  666. init();
  667. lex(source);
  668. jit_main = parser();
  669. jit_main(0, funcTable);
  670. dispose();
  671. return 0;
  672. }
  673.  
  674. enum {
  675. L_START,
  676. L__MAX
  677. };
  678.  
  679. static const unsigned char euboeaactions[269] = {
  680. 252,233,245,255,133,192,15,133,244,247,252,233,245,248,1,255,249,255,252,
  681. 233,245,249,255,249,85,137,229,129,252,236,0,0,0,128,249,255,139,133,233,
  682. 137,133,233,255,201,195,255,249,85,137,229,129,252,236,0,0,0,128,249,139,
  683. 181,233,255,184,237,255,80,255,252,255,150,233,255,252,255,22,255,131,196,
  684. 4,255,184,237,137,4,36,255,137,132,253,36,233,255,248,10,252,233,245,255,
  685. 139,141,233,90,255,137,4,145,255,137,4,17,255,139,133,233,80,255,64,255,72,
  686. 255,88,255,139,13,237,90,255,137,4,18,255,163,237,255,161,237,80,255,137,
  687. 193,255,139,149,233,255,139,21,237,255,139,4,138,255,15,182,4,10,255,232,
  688. 245,129,196,239,255,139,133,233,255,161,237,255,139,4,129,255,137,195,88,
  689. 255,252,247,252,235,255,49,210,252,247,252,251,255,49,210,252,247,252,251,
  690. 137,208,255,1,216,255,41,216,255,137,195,88,57,216,255,15,156,208,255,15,
  691. 159,208,255,15,149,208,255,15,148,208,255,15,158,208,255,15,157,208,255,15,
  692. 182,192,255,33,216,255,9,216,255,49,216,255,193,224,2,137,4,36,252,255,150,
  693. 233,80,137,4,36,252,255,150,233,88,255
  694. };
  695.  
  696. dasm_State * d;
  697.  
  698. static dasm_State ** Dst = &d;
  699.  
  700. void * euboealabels[L__MAX];
  701. void * jit_buf;
  702.  
  703. size_t jit_sz;
  704. int npc;
  705. static int main_address, mainFunc;
  706.  
  707. struct {
  708. var_t var[0xFF];
  709. int count;
  710. int data[0xFF];
  711. } gvar_t;
  712.  
  713. struct {
  714. var_t var[0xFF][0xFF];
  715. int count, size[0xFF];
  716. } lvar_t;
  717.  
  718. struct {
  719. char * text[0xff];
  720. int * addr;
  721. int count;
  722. } str_t;
  723.  
  724. struct {
  725. func_t func[0xff];
  726. int count, inside, now;
  727. } fnc_t;
  728.  
  729. void initjit() {
  730. dasm_init(&d, 1);
  731. dasm_setupglobal(&d, euboealabels, L__MAX);
  732. dasm_setup(&d, euboeaactions);
  733. }
  734.  
  735. void * deinitjit() {
  736. dasm_link(&d, &jit_sz);
  737. jit_buf = mmap(0, jit_sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  738. dasm_encode(&d, jit_buf);
  739. mprotect(jit_buf, jit_sz, PROT_READ | PROT_WRITE | PROT_EXEC);
  740. return jit_buf;
  741. }
  742.  
  743. char * getstr() {
  744. str_t.text[str_t.count] = calloc(sizeof(char), strlen(tok_t.tok_t[tok_t.pos].val) + 1);
  745. strcpy(str_t.text[str_t.count], tok_t.tok_t[tok_t.pos++].val);
  746. return str_t.text[str_t.count++];
  747. }
  748.  
  749. var_t * getvar(char * name) {
  750. int i = 0;
  751. for (; i < lvar_t.count; i++) {
  752. if (!strcmp(name, lvar_t.var[fnc_t.now][i].name))
  753. return &lvar_t.var[fnc_t.now][i];
  754. }
  755. for (i = 0; i < gvar_t.count; i++) {
  756. if (!strcmp(name, gvar_t.var[i].name))
  757. return &gvar_t.var[i];
  758. }
  759. return NULL;
  760. }
  761.  
  762. static var_t * appvar(char * name, int type) {
  763. if (fnc_t.inside == IN_FUNC) {
  764. int32_t sz = 1 + ++lvar_t.size[fnc_t.now];
  765. strcpy(lvar_t.var[fnc_t.now][lvar_t.count].name, name);
  766. lvar_t.var[fnc_t.now][lvar_t.count].type = type;
  767. lvar_t.var[fnc_t.now][lvar_t.count].id = sz;
  768. lvar_t.var[fnc_t.now][lvar_t.count].loctype = V_LOCAL;
  769. return &lvar_t.var[fnc_t.now][lvar_t.count++];
  770. } else if (fnc_t.inside == IN_GLOBAL) {
  771. strcpy(gvar_t.var[gvar_t.count].name, name);
  772. gvar_t.var[gvar_t.count].type = type;
  773. gvar_t.var[gvar_t.count].loctype = V_GLOBAL;
  774. gvar_t.var[gvar_t.count].id = (int)&gvar_t.data[gvar_t.count];
  775. return &gvar_t.var[gvar_t.count++];
  776. }
  777. return NULL;
  778. }
  779.  
  780. func_t * getfn(char * name) {
  781. int i = 0;
  782. for (; i < fnc_t.count; i++) {
  783. if (!strcmp(fnc_t.func[i].name, name))
  784. return &fnc_t.func[i];
  785. }
  786. return NULL;
  787. }
  788.  
  789. static func_t * appfn(char * name, int address, int espBgn, int args) {
  790. fnc_t.func[fnc_t.count].address = address;
  791. fnc_t.func[fnc_t.count].espBgn = espBgn;
  792. fnc_t.func[fnc_t.count].args = args;
  793. strcpy(fnc_t.func[fnc_t.count].name, name);
  794. return &fnc_t.func[fnc_t.count++];
  795. }
  796.  
  797. static int32_t mkbrk() {
  798. uint32_t lbl = npc++;
  799. dasm_growpc(&d, npc);
  800. dasm_put(Dst, 0, lbl);
  801. brks_t.addr = realloc(brks_t.addr, 4 * (brks_t.count + 1));
  802. brks_t.addr[brks_t.count] = lbl;
  803. return brks_t.count++;
  804. }
  805.  
  806. static int32_t mkret() {
  807. cmpexpr();
  808. int lbl = npc++;
  809. dasm_growpc(&d, npc);
  810. dasm_put(Dst, 0, lbl);
  811. rets_t.addr = realloc(rets_t.addr, 4 * (rets_t.count + 1));
  812. if (rets_t.addr == NULL) error("no enough memory");
  813. rets_t.addr[rets_t.count] = lbl;
  814. return rets_t.count++;
  815. }
  816.  
  817. int32_t skip(char * s) {
  818. if (!strcmp(s, tok_t.tok_t[tok_t.pos].val)) {
  819. tok_t.pos++;
  820. return 1;
  821. }
  822. return 0;
  823. }
  824.  
  825. int32_t error(char * errs, ...) {
  826. va_list args;
  827. va_start(args, errs);
  828. printf("error: ");
  829. vprintf(errs, args);
  830. puts("");
  831. va_end(args);
  832. exit(0);
  833. return 0;
  834. }
  835.  
  836. static int eval(int pos, int status) {
  837. while (tok_t.pos < tok_t.size)
  838. if (expression(pos, status)) return 1;
  839. return 0;
  840. }
  841.  
  842. static var_t * mkvar() {
  843. int32_t npos = tok_t.pos;
  844. if (isalpha(tok_t.tok_t[tok_t.pos].val[0])) {
  845. tok_t.pos++;
  846. if (skip(":")) {
  847. if (skip("int")) {
  848. --tok_t.pos;
  849. return appvar(tok_t.tok_t[npos].val, T_INT);
  850. }
  851. if (skip("string")) {
  852. --tok_t.pos;
  853. return appvar(tok_t.tok_t[npos].val, T_STRING);
  854. }
  855. if (skip("double")) {
  856. --tok_t.pos;
  857. return appvar(tok_t.tok_t[npos].val, T_DOUBLE);
  858. }
  859. } else {
  860. --tok_t.pos;
  861. return appvar(tok_t.tok_t[npos].val, T_INT);
  862. }
  863. } else error("%d: can't declare variable", tok_t.tok_t[tok_t.pos].nline);
  864. return NULL;
  865. }
  866.  
  867. static int chkstmt() {
  868. cmpexpr();
  869. uint32_t end = npc++;
  870. dasm_growpc(&d, npc);
  871. dasm_put(Dst, 4, end);
  872. return eval(end, 0);
  873. }
  874.  
  875. static int whilestmt() {
  876. uint32_t loopBgn = npc++;
  877. dasm_growpc(&d, npc);
  878. dasm_put(Dst, 16, loopBgn);
  879. cmpexpr();
  880. uint32_t stepBgn[2], stepOn = 0;
  881. if (skip(",")) {
  882. stepOn = 1;
  883. stepBgn[0] = tok_t.pos;
  884. for (; tok_t.tok_t[tok_t.pos].val[0] != ';'; tok_t.pos++);
  885. }
  886. uint32_t end = npc++;
  887. dasm_growpc(&d, npc);
  888. dasm_put(Dst, 4, end);
  889. if (skip(":")) expression(0, BLOCK_LOOP);
  890. else eval(0, BLOCK_LOOP);
  891. if (stepOn) {
  892. stepBgn[1] = tok_t.pos;
  893. tok_t.pos = stepBgn[0];
  894. if (isassign()) assignment();
  895. tok_t.pos = stepBgn[1];
  896. }
  897. dasm_put(Dst, 18, loopBgn, end);
  898. for (--brks_t.count; brks_t.count >= 0; brks_t.count--)
  899. dasm_put(Dst, 16, brks_t.addr[brks_t.count]);
  900. brks_t.count = 0;
  901. return 0;
  902. }
  903.  
  904. static int32_t fnstmt() {
  905. int32_t argsc = 0;
  906. int i = 0;
  907. char * funcName = tok_t.tok_t[tok_t.pos++].val;
  908. fnc_t.now++; fnc_t.inside = IN_FUNC;
  909. if (skip("(")) {
  910. do {
  911. mkvar();
  912. tok_t.pos++;
  913. argsc++;
  914. } while (skip(","));
  915. if (!skip(")"))
  916. error("%d: expecting ')'", tok_t.tok_t[tok_t.pos].nline);
  917. }
  918. int func_addr = npc++;
  919. dasm_growpc(&d, npc);
  920. int func_esp = npc++;
  921. dasm_growpc(&d, npc);
  922. appfn(funcName, func_addr, func_esp, argsc);
  923. dasm_put(Dst, 23, func_addr, func_esp);
  924. for (; i < argsc; i++)
  925. dasm_put(Dst, 36, ((argsc - i - 1) * sizeof(int32_t) + 8), - (i + 2)*4);
  926. eval(0, BLOCK_FUNC);
  927. for (--rets_t.count; rets_t.count >= 0; --rets_t.count)
  928. dasm_put(Dst, 16, rets_t.addr[rets_t.count]);
  929. rets_t.count = 0;
  930. dasm_put(Dst, 43);
  931. return 0;
  932. }
  933.  
  934. int expression(int pos, int status) {
  935. int isputs = 0;
  936. if (skip("$")) {
  937. if (isassign()) assignment();
  938. } else if (skip("def"))
  939. fnstmt();
  940. else if (fnc_t.inside == IN_GLOBAL &&
  941. strcmp("def", tok_t.tok_t[tok_t.pos+1].val) &&
  942. strcmp("$", tok_t.tok_t[tok_t.pos+1].val) &&
  943. (tok_t.pos+1 == tok_t.size || strcmp(";", tok_t.tok_t[tok_t.pos+1].val))) {
  944. fnc_t.inside = IN_FUNC;
  945. mainFunc = ++fnc_t.now;
  946. int main_esp = npc++;
  947. dasm_growpc(&d, npc);
  948. appfn("main", main_address, main_esp, 0);
  949. dasm_put(Dst, 46, main_address, main_esp, 12);
  950. eval(0, 0);
  951. dasm_put(Dst, 43);
  952. fnc_t.inside = IN_GLOBAL;
  953. } else if (isassign())
  954. assignment();
  955. else if ((isputs = skip("puts")) || skip("output")) {
  956. do {
  957. int isstring = 0;
  958. if (skip(""")) {
  959. dasm_put(Dst, 62, getstr());
  960. isstring = 1;
  961. } else
  962. cmpexpr();
  963. dasm_put(Dst, 65);
  964. if (isstring)
  965. dasm_put(Dst, 67, 4);
  966.  
  967. else
  968. dasm_put(Dst, 72);
  969. dasm_put(Dst, 76);
  970. } while (skip(","));
  971. if (isputs)
  972. dasm_put(Dst, 67, 0x8);
  973. } else if (skip("printf")) {
  974. if (skip("""))
  975. dasm_put(Dst, 80, getstr());
  976. if (skip(",")) {
  977. uint32_t a = 4;
  978. do {
  979. cmpexpr();
  980. dasm_put(Dst, 86, a);
  981. a += 4;
  982. } while (skip(","));
  983. }
  984. dasm_put(Dst, 67, 0x14);
  985. } else if (skip("for")) {
  986. assignment();
  987. if (!skip(","))
  988. error("%d: expecting ','", tok_t.tok_t[tok_t.pos].nline);
  989. whilestmt();
  990. } else if (skip("while"))
  991. whilestmt();
  992. else if (skip("return"))
  993. mkret();
  994. else if (skip("if"))
  995. chkstmt();
  996. else if (skip("else")) {
  997. int32_t end = npc++;
  998. dasm_growpc(&d, npc);
  999. dasm_put(Dst, 18, end, pos);
  1000. eval(end, 0);
  1001. return 1;
  1002. } else if (skip("elsif")) {
  1003. int32_t endif = npc++;
  1004. dasm_growpc(&d, npc);
  1005. dasm_put(Dst, 18, endif, pos);
  1006. cmpexpr();
  1007. uint32_t end = npc++;
  1008. dasm_growpc(&d, npc);
  1009. dasm_put(Dst, 4, end);
  1010. eval(end, 0);
  1011. dasm_put(Dst, 16, endif);
  1012. return 1;
  1013. } else if (skip("break"))
  1014. mkbrk();
  1015. else if (skip("end")) {
  1016. if (status == 0)
  1017. dasm_put(Dst, 16, pos);
  1018.  
  1019. else if (status == BLOCK_FUNC) fnc_t.inside = IN_GLOBAL;
  1020. return 1;
  1021. } else if (!skip(";")) cmpexpr();
  1022. return 0;
  1023. }
  1024.  
  1025. static char * repescape(char * str) {
  1026. char escape[14][3] = {
  1027. "\a", "a", "\r", "r", "\f", "f",
  1028. "\n", "n", "\t", "t", "\b", "b",
  1029. "\q", """
  1030. };
  1031. int32_t i = 0;
  1032. for (; i < 12; i += 2) {
  1033. char * pos;
  1034. while ((pos = strstr(str, escape[i])) != NULL) {
  1035. *pos = escape[i + 1][0];
  1036. memmove(pos + 1, pos + 2, strlen(pos + 2) + 1);
  1037. }
  1038. }
  1039. return str;
  1040. }
  1041.  
  1042. int (*parser())(int *, void **) {
  1043. int i;
  1044. uint8_t * buf;
  1045. initjit();
  1046. tok_t.pos = 0;
  1047. str_t.addr = calloc(0xFF, sizeof(int32_t));
  1048. main_address = npc++;
  1049. dasm_growpc(&d, npc);
  1050. dasm_put(Dst, 92, main_address);
  1051. eval(0, 0);
  1052. for (i = 0; i < str_t.count; ++i)
  1053. repescape(str_t.text[i]);
  1054. buf = (uint8_t *)deinitjit();
  1055. for (i = 0; i < fnc_t.count; i++)
  1056. *(int *)(buf + dasm_getpclabel(&d, fnc_t.func[i].espBgn) - 4) = (lvar_t.size[i+1] + 6)*4;
  1057. dasm_free(&d);
  1058. return ((int (*)(int *, void **))euboealabels[L_START]);
  1059. }
  1060.  
  1061. int32_t isassign() {
  1062. char * val = tok_t.tok_t[tok_t.pos + 1].val;
  1063. if (!strcmp(val, "=") || !strcmp(val, "++") || !strcmp(val, "--")) return 1;
  1064. if (!strcmp(val, "[")) {
  1065. int32_t i = tok_t.pos + 2, t = 1;
  1066. while (t) {
  1067. val = tok_t.tok_t[i].val;
  1068. if (!strcmp(val, "[")) t++;
  1069. if (!strcmp(val, "]")) t--;
  1070. if (!strcmp(val, ";"))
  1071. error("%d: invalid expression", tok_t.tok_t[tok_t.pos].nline);
  1072. i++;
  1073. }
  1074. if (!strcmp(tok_t.tok_t[i].val, "=")) return 1;
  1075. } else if (!strcmp(val, ":") && !strcmp(tok_t.tok_t[tok_t.pos + 3].val, "="))
  1076. return 1;
  1077. return 0;
  1078. }
  1079.  
  1080. int32_t assignment() {
  1081. var_t * v = getvar(tok_t.tok_t[tok_t.pos].val);
  1082. int32_t inc = 0, dec = 0, declare = 0;
  1083. if (v == NULL) {
  1084. declare++;
  1085. v = mkvar();
  1086. }
  1087. tok_t.pos++;
  1088. int siz = (v->type == T_INT ? sizeof(int32_t) : v->type == T_STRING ? sizeof(int32_t *) : v->type == T_DOUBLE ? sizeof(double) : 4);
  1089. if (v->loctype == V_LOCAL) {
  1090. if (skip("[")) {
  1091. cmpexpr();
  1092. dasm_put(Dst, 65);
  1093. if (skip("]") && skip("=")) {
  1094. cmpexpr();
  1095. dasm_put(Dst, 98, - siz*v->id);
  1096. if (v->type == T_INT)
  1097. dasm_put(Dst, 103);
  1098.  
  1099. else
  1100. dasm_put(Dst, 107);
  1101. } else if ((inc = skip("++")) || (dec = skip("--"))) {
  1102. } else
  1103. error("%d: invalid assignment", tok_t.tok_t[tok_t.pos].nline);
  1104. } else {
  1105. if (skip("="))
  1106. cmpexpr();
  1107. else if ((inc = skip("++")) || (dec = skip("--"))) {
  1108. dasm_put(Dst, 111, - siz*v->id);
  1109. if (inc)
  1110. dasm_put(Dst, 116);
  1111. else if (dec)
  1112. dasm_put(Dst, 118);
  1113. }
  1114. dasm_put(Dst, 39, - siz*v->id);
  1115. if (inc || dec)
  1116. dasm_put(Dst, 120);
  1117. }
  1118. } else if (v->loctype == V_GLOBAL) {
  1119. if (declare) {
  1120. if (skip("=")) {
  1121. unsigned * m = (unsigned *) v->id;
  1122. *m = atoi(tok_t.tok_t[tok_t.pos++].val);
  1123. }
  1124. } else {
  1125. if (skip("[")) {
  1126. cmpexpr();
  1127. dasm_put(Dst, 65);
  1128. if (skip("]") && skip("=")) {
  1129. cmpexpr();
  1130. dasm_put(Dst, 122, v->id);
  1131. if (v->type == T_INT)
  1132. dasm_put(Dst, 103);
  1133.  
  1134. else
  1135. dasm_put(Dst, 127);
  1136. } else error("%d: invalid assignment",
  1137. tok_t.tok_t[tok_t.pos].nline);
  1138. } else if (skip("=")) {
  1139. cmpexpr();
  1140. dasm_put(Dst, 131, v->id);
  1141. } else if ((inc = skip("++")) || (dec = skip("--"))) {
  1142. dasm_put(Dst, 134, v->id);
  1143. if (inc)
  1144. dasm_put(Dst, 116);
  1145. else if (dec)
  1146. dasm_put(Dst, 118);
  1147. dasm_put(Dst, 131, v->id);
  1148. }
  1149. if (inc || dec)
  1150. dasm_put(Dst, 120);
  1151. }
  1152. }
  1153. return 0;
  1154. }
  1155. extern int buildstd(char *);
  1156.  
  1157. static int32_t isidx() {
  1158. return !strcmp(tok_t.tok_t[tok_t.pos].val, "[");
  1159. }
  1160.  
  1161. static void priexp() {
  1162. if (isdigit(tok_t.tok_t[tok_t.pos].val[0]))
  1163. dasm_put(Dst, 62, atoi(tok_t.tok_t[tok_t.pos++].val));
  1164.  
  1165. else if (skip("'")) {
  1166. dasm_put(Dst, 62, tok_t.tok_t[tok_t.pos++].val[0]);
  1167. skip("'");
  1168. } else if (skip("""))
  1169. dasm_put(Dst, 62, getstr());
  1170.  
  1171. else if (isalpha(tok_t.tok_t[tok_t.pos].val[0])) {
  1172. char * name = tok_t.tok_t[tok_t.pos].val;
  1173. var_t * v;
  1174. if (isassign()) assignment();
  1175. else {
  1176. tok_t.pos++;
  1177. if (skip("[")) {
  1178. if ((v = getvar(name)) == NULL)
  1179. error("%d: '%s' was not declared",
  1180. tok_t.tok_t[tok_t.pos].nline, name);
  1181. cmpexpr();
  1182. dasm_put(Dst, 138);
  1183. if (v->loctype == V_LOCAL)
  1184. dasm_put(Dst, 141, - v->id*4);
  1185.  
  1186. else if (v->loctype == V_GLOBAL)
  1187. dasm_put(Dst, 145, v->id);
  1188. if (v->type == T_INT)
  1189. dasm_put(Dst, 149);
  1190.  
  1191. else
  1192. dasm_put(Dst, 153);
  1193. if (!skip("]"))
  1194. error("%d: expected expression ']'",
  1195. tok_t.tok_t[tok_t.pos].nline);
  1196. } else if (skip("(")) {
  1197. if (!buildstd(name)) {
  1198. func_t * function = getfn(name);
  1199. char * val = tok_t.tok_t[tok_t.pos].val;
  1200. int i = 0;
  1201. if (isalpha(val[0]) || isdigit(val[0]) ||
  1202. !strcmp(val, """) || !strcmp(val, "(")) {
  1203. for (; i < function->args; i++) {
  1204. cmpexpr();
  1205. dasm_put(Dst, 65);
  1206. skip(",");
  1207. }
  1208. }
  1209. dasm_put(Dst, 158, function->address, function->args * sizeof(int32_t));
  1210. }
  1211. if (!skip(")"))
  1212. error("func: %d: expected expression ')'",
  1213. tok_t.tok_t[tok_t.pos].nline);
  1214. } else {
  1215. if ((v = getvar(name)) == NULL)
  1216. error("var: %d: '%s' was not declared",
  1217. tok_t.tok_t[tok_t.pos].nline, name);
  1218. if (v->loctype == V_LOCAL)
  1219. dasm_put(Dst, 164, - v->id*4);
  1220.  
  1221. else if (v->loctype == V_GLOBAL)
  1222. dasm_put(Dst, 168, v->id);
  1223. }
  1224. }
  1225. } else if (skip("(")) {
  1226. if (isassign()) assignment();
  1227. else cmpexpr();
  1228. if (!skip(")")) error("%d: expected expression ')'", tok_t.tok_t[tok_t.pos].nline);
  1229. }
  1230. while (isidx()) {
  1231. dasm_put(Dst, 138);
  1232. skip("[");
  1233. cmpexpr();
  1234. skip("]");
  1235. dasm_put(Dst, 171);
  1236. }
  1237. }
  1238.  
  1239. static void muldivexp() {
  1240. int32_t mul = 0, div = 0;
  1241. priexp();
  1242. while ((mul = skip("*")) || (div = skip("/")) || skip("%")) {
  1243. dasm_put(Dst, 65);
  1244. priexp();
  1245. dasm_put(Dst, 175);
  1246. if (mul)
  1247. dasm_put(Dst, 179);
  1248.  
  1249. else if (div)
  1250. dasm_put(Dst, 184);
  1251.  
  1252. else
  1253. dasm_put(Dst, 191);
  1254. }
  1255. }
  1256.  
  1257. static void addSubExpr() {
  1258. int32_t add;
  1259. muldivexp();
  1260. while ((add = skip("+")) || skip("-")) {
  1261. dasm_put(Dst, 65);
  1262. muldivexp();
  1263. dasm_put(Dst, 175);
  1264. if (add)
  1265. dasm_put(Dst, 200);
  1266.  
  1267. else
  1268. dasm_put(Dst, 203);
  1269. }
  1270. }
  1271.  
  1272. static void logicexp() {
  1273. int32_t lt = 0, gt = 0, ne = 0, eql = 0, fle = 0;
  1274. addSubExpr();
  1275. if ((lt = skip("<")) || (gt = skip(">")) || (ne = skip("!=")) ||
  1276. (eql = skip("==")) || (fle = skip("<=")) || skip(">=")) {
  1277. dasm_put(Dst, 65);
  1278. addSubExpr();
  1279. dasm_put(Dst, 206);
  1280. if (lt)
  1281. dasm_put(Dst, 212);
  1282. else if (gt)
  1283. dasm_put(Dst, 216);
  1284. else if (ne)
  1285. dasm_put(Dst, 220);
  1286. else if (eql)
  1287. dasm_put(Dst, 224);
  1288. else if (fle)
  1289. dasm_put(Dst, 228);
  1290. else
  1291. dasm_put(Dst, 232);
  1292. dasm_put(Dst, 236);
  1293. }
  1294. }
  1295.  
  1296. void cmpexpr() {
  1297. int and = 0, or = 0;
  1298. logicexp();
  1299. while ((and = skip("and") || skip("&")) ||
  1300. (or = skip("or") || skip("|")) || (skip("xor") || skip("^"))) {
  1301. dasm_put(Dst, 65);
  1302. logicexp();
  1303. dasm_put(Dst, 175);
  1304. if (and)
  1305. dasm_put(Dst, 240);
  1306. else if (or)
  1307. dasm_put(Dst, 243);
  1308. else
  1309. dasm_put(Dst, 246);
  1310. }
  1311. }
  1312.  
  1313. typedef struct {
  1314. char * name;
  1315. int args, addr;
  1316. } stdfn;
  1317.  
  1318. static stdfn stdfuncts[] = {
  1319. {"Array", 1, 12},
  1320. {"rand", 0, 16}, {"printf", -1, 20}, {"usleep", 1, 28},
  1321. {"fprintf", -1, 36}, {"fgets", 3, 44},
  1322. {"free", 1, 48}, {"freeLocal", 0, 52}, {"malloc", 1, 12}, {"exit", 1, 56},
  1323. {"abort", 0, 60}, {"read", 3, 32}, {"write", 3, 40}, {"close", 1, 64}
  1324. };
  1325.  
  1326. int buildstd(char * name) {
  1327. size_t i = 0;
  1328. for (; i < sizeof(stdfuncts) / sizeof(stdfuncts[0]); i++) {
  1329. if (!strcmp(stdfuncts[i].name, name)) {
  1330. if (!strcmp(name, "Array")) {
  1331. cmpexpr();
  1332. dasm_put(Dst, 249, 12, 24);
  1333. } else {
  1334. if (stdfuncts[i].args == -1) {
  1335. uint32_t a = 0;
  1336. do {
  1337. cmpexpr();
  1338. dasm_put(Dst, 86, a);
  1339. a += 4;
  1340. } while (skip(","));
  1341. } else {
  1342. int arg = 0;
  1343. for (; arg < stdfuncts[i].args; arg++) {
  1344. cmpexpr();
  1345. dasm_put(Dst, 86, arg*4);
  1346. skip(",");
  1347. }
  1348. }
  1349. dasm_put(Dst, 67, stdfuncts[i].addr);
  1350. }
  1351. return 1;
  1352. }
  1353. }
  1354. return 0;
  1355. }
  1356.  
  1357. int main(int argc, char ** argv) {
  1358. char * src;
  1359. FILE * fp;
  1360. size_t ssz;
  1361. if (argc < 2) error("no given filename");
  1362. fp = fopen(argv[1], "rb");
  1363. ssz = 0;
  1364. if (!fp) {
  1365. perror("fopen");
  1366. exit(0);
  1367. }
  1368. struct stat sbuf;
  1369. stat(argv[1], &sbuf);
  1370. if (S_ISDIR(sbuf.st_mode)) {
  1371. fclose(fp);
  1372. printf("Error: %s is a directory.n", argv[1]);
  1373. exit(0);
  1374. }
  1375. fseek(fp, 0, SEEK_END);
  1376. ssz = ftell(fp);
  1377. fseek(fp, 0, SEEK_SET);
  1378. src = calloc(sizeof(char), ssz + 2);
  1379. fread(src, sizeof(char), ssz, fp);
  1380. fclose(fp);
  1381. return execute(src);
  1382. }
Add Comment
Please, Sign In to add comment