xec.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698
  1. #include <lib9.h>
  2. #include "isa.h"
  3. #include "interp.h"
  4. #include "raise.h"
  5. #include "pool.h"
  6. REG R; /* Virtual Machine registers */
  7. String snil; /* String known to be zero length */
  8. #define Stmp *((WORD*)(R.FP+NREG*IBY2WD))
  9. #define Dtmp *((WORD*)(R.FP+(NREG+2)*IBY2WD))
  10. #define OP(fn) void fn(void)
  11. #define B(r) *((BYTE*)(R.r))
  12. #define W(r) *((WORD*)(R.r))
  13. #define UW(r) *((UWORD*)(R.r))
  14. #define F(r) *((REAL*)(R.r))
  15. #define V(r) *((LONG*)(R.r))
  16. #define UV(r) *((ULONG*)(R.r))
  17. #define S(r) *((String**)(R.r))
  18. #define A(r) *((Array**)(R.r))
  19. #define L(r) *((List**)(R.r))
  20. #define P(r) *((WORD**)(R.r))
  21. #define C(r) *((Channel**)(R.r))
  22. #define T(r) *((void**)(R.r))
  23. #define JMP(r) R.PC = *(Inst**)(R.r)
  24. #define SH(r) *((SHORT*)(R.r))
  25. #define SR(r) *((SREAL*)(R.r))
  26. OP(runt) {}
  27. OP(negf) { F(d) = -F(s); }
  28. OP(jmp) { JMP(d); }
  29. OP(movpc){ T(d) = &R.M->prog[W(s)]; }
  30. OP(movm) { memmove(R.d, R.s, W(m)); }
  31. OP(lea) { W(d) = (WORD)R.s; }
  32. OP(movb) { B(d) = B(s); }
  33. OP(movw) { W(d) = W(s); }
  34. OP(movf) { F(d) = F(s); }
  35. OP(movl) { V(d) = V(s); }
  36. OP(cvtbw){ W(d) = B(s); }
  37. OP(cvtwb){ B(d) = W(s); }
  38. OP(cvtrf){ F(d) = SR(s); }
  39. OP(cvtfr){ SR(d) = F(s); }
  40. OP(cvtws){ SH(d) = W(s); }
  41. OP(cvtsw){ W(d) = SH(s); }
  42. OP(cvtwf){ F(d) = W(s); }
  43. OP(addb) { B(d) = B(m) + B(s); }
  44. OP(addw) { W(d) = W(m) + W(s); }
  45. OP(addl) { V(d) = V(m) + V(s); }
  46. OP(addf) { F(d) = F(m) + F(s); }
  47. OP(subb) { B(d) = B(m) - B(s); }
  48. OP(subw) { W(d) = W(m) - W(s); }
  49. OP(subl) { V(d) = V(m) - V(s); }
  50. OP(subf) { F(d) = F(m) - F(s); }
  51. OP(divb) { B(d) = B(m) / B(s); }
  52. OP(divw) { W(d) = W(m) / W(s); }
  53. OP(divl) { V(d) = V(m) / V(s); }
  54. OP(divf) { F(d) = F(m) / F(s); }
  55. OP(modb) { B(d) = B(m) % B(s); }
  56. OP(modw) { W(d) = W(m) % W(s); }
  57. OP(modl) { V(d) = V(m) % V(s); }
  58. OP(mulb) { B(d) = B(m) * B(s); }
  59. OP(mulw) { W(d) = W(m) * W(s); }
  60. OP(mull) { V(d) = V(m) * V(s); }
  61. OP(mulf) { F(d) = F(m) * F(s); }
  62. OP(andb) { B(d) = B(m) & B(s); }
  63. OP(andw) { W(d) = W(m) & W(s); }
  64. OP(andl) { V(d) = V(m) & V(s); }
  65. OP(xorb) { B(d) = B(m) ^ B(s); }
  66. OP(xorw) { W(d) = W(m) ^ W(s); }
  67. OP(xorl) { V(d) = V(m) ^ V(s); }
  68. OP(orb) { B(d) = B(m) | B(s); }
  69. OP(orw) { W(d) = W(m) | W(s); }
  70. OP(orl) { V(d) = V(m) | V(s); }
  71. OP(shlb) { B(d) = B(m) << W(s); }
  72. OP(shlw) { W(d) = W(m) << W(s); }
  73. OP(shll) { V(d) = V(m) << W(s); }
  74. OP(shrb) { B(d) = B(m) >> W(s); }
  75. OP(shrw) { W(d) = W(m) >> W(s); }
  76. OP(shrl) { V(d) = V(m) >> W(s); }
  77. OP(lsrw) { W(d) = UW(m) >> W(s); }
  78. OP(lsrl) { V(d) = UV(m) >> W(s); }
  79. OP(beqb) { if(B(s) == B(m)) JMP(d); }
  80. OP(bneb) { if(B(s) != B(m)) JMP(d); }
  81. OP(bltb) { if(B(s) < B(m)) JMP(d); }
  82. OP(bleb) { if(B(s) <= B(m)) JMP(d); }
  83. OP(bgtb) { if(B(s) > B(m)) JMP(d); }
  84. OP(bgeb) { if(B(s) >= B(m)) JMP(d); }
  85. OP(beqw) { if(W(s) == W(m)) JMP(d); }
  86. OP(bnew) { if(W(s) != W(m)) JMP(d); }
  87. OP(bltw) { if(W(s) < W(m)) JMP(d); }
  88. OP(blew) { if(W(s) <= W(m)) JMP(d); }
  89. OP(bgtw) { if(W(s) > W(m)) JMP(d); }
  90. OP(bgew) { if(W(s) >= W(m)) JMP(d); }
  91. OP(beql) { if(V(s) == V(m)) JMP(d); }
  92. OP(bnel) { if(V(s) != V(m)) JMP(d); }
  93. OP(bltl) { if(V(s) < V(m)) JMP(d); }
  94. OP(blel) { if(V(s) <= V(m)) JMP(d); }
  95. OP(bgtl) { if(V(s) > V(m)) JMP(d); }
  96. OP(bgel) { if(V(s) >= V(m)) JMP(d); }
  97. OP(beqf) { if(F(s) == F(m)) JMP(d); }
  98. OP(bnef) { if(F(s) != F(m)) JMP(d); }
  99. OP(bltf) { if(F(s) < F(m)) JMP(d); }
  100. OP(blef) { if(F(s) <= F(m)) JMP(d); }
  101. OP(bgtf) { if(F(s) > F(m)) JMP(d); }
  102. OP(bgef) { if(F(s) >= F(m)) JMP(d); }
  103. OP(beqc) { if(stringcmp(S(s), S(m)) == 0) JMP(d); }
  104. OP(bnec) { if(stringcmp(S(s), S(m)) != 0) JMP(d); }
  105. OP(bltc) { if(stringcmp(S(s), S(m)) < 0) JMP(d); }
  106. OP(blec) { if(stringcmp(S(s), S(m)) <= 0) JMP(d); }
  107. OP(bgtc) { if(stringcmp(S(s), S(m)) > 0) JMP(d); }
  108. OP(bgec) { if(stringcmp(S(s), S(m)) >= 0) JMP(d); }
  109. OP(iexit){ error(""); }
  110. OP(cvtwl){ V(d) = W(s); }
  111. OP(cvtlw){ W(d) = V(s); }
  112. OP(cvtlf){ F(d) = V(s); }
  113. OP(cvtfl)
  114. {
  115. REAL f;
  116. f = F(s);
  117. V(d) = f < 0 ? f - .5 : f + .5;
  118. }
  119. OP(cvtfw)
  120. {
  121. REAL f;
  122. f = F(s);
  123. W(d) = f < 0 ? f - .5 : f + .5;
  124. }
  125. OP(cvtcl)
  126. {
  127. String *s;
  128. s = S(s);
  129. if(s == H)
  130. V(d) = 0;
  131. else
  132. V(d) = strtoll(string2c(s), nil, 10);
  133. }
  134. OP(iexpw)
  135. {
  136. int inv;
  137. WORD x, n, r;
  138. x = W(m);
  139. n = W(s);
  140. inv = 0;
  141. if(n < 0){
  142. n = -n;
  143. inv = 1;
  144. }
  145. r = 1;
  146. for(;;){
  147. if(n&1)
  148. r *= x;
  149. if((n >>= 1) == 0)
  150. break;
  151. x *= x;
  152. }
  153. if(inv)
  154. r = 1/r;
  155. W(d) = r;
  156. }
  157. OP(iexpl)
  158. {
  159. int inv;
  160. WORD n;
  161. LONG x, r;
  162. x = V(m);
  163. n = W(s);
  164. inv = 0;
  165. if(n < 0){
  166. n = -n;
  167. inv = 1;
  168. }
  169. r = 1;
  170. for(;;){
  171. if(n&1)
  172. r *= x;
  173. if((n >>= 1) == 0)
  174. break;
  175. x *= x;
  176. }
  177. if(inv)
  178. r = 1/r;
  179. V(d) = r;
  180. }
  181. OP(iexpf)
  182. {
  183. int inv;
  184. WORD n;
  185. REAL x, r;
  186. x = F(m);
  187. n = W(s);
  188. inv = 0;
  189. if(n < 0){
  190. n = -n;
  191. inv = 1;
  192. }
  193. r = 1;
  194. for(;;){
  195. if(n&1)
  196. r *= x;
  197. if((n >>= 1) == 0)
  198. break;
  199. x *= x;
  200. }
  201. if(inv)
  202. r = 1/r;
  203. F(d) = r;
  204. }
  205. OP(indx)
  206. {
  207. ulong i;
  208. Array *a;
  209. a = A(s);
  210. i = W(d);
  211. if(a == H || i >= a->len)
  212. error(exBounds);
  213. W(m) = (WORD)(a->data+i*a->t->size);
  214. }
  215. OP(indw)
  216. {
  217. ulong i;
  218. Array *a;
  219. a = A(s);
  220. i = W(d);
  221. if(a == H || i >= a->len)
  222. error(exBounds);
  223. W(m) = (WORD)(a->data+i*sizeof(WORD));
  224. }
  225. OP(indf)
  226. {
  227. ulong i;
  228. Array *a;
  229. a = A(s);
  230. i = W(d);
  231. if(a == H || i >= a->len)
  232. error(exBounds);
  233. W(m) = (WORD)(a->data+i*sizeof(REAL));
  234. }
  235. OP(indl)
  236. {
  237. ulong i;
  238. Array *a;
  239. a = A(s);
  240. i = W(d);
  241. if(a == H || i >= a->len)
  242. error(exBounds);
  243. W(m) = (WORD)(a->data+i*sizeof(LONG));
  244. }
  245. OP(indb)
  246. {
  247. ulong i;
  248. Array *a;
  249. a = A(s);
  250. i = W(d);
  251. if(a == H || i >= a->len)
  252. error(exBounds);
  253. W(m) = (WORD)(a->data+i*sizeof(BYTE));
  254. }
  255. OP(movp)
  256. {
  257. Heap *h;
  258. WORD *dv, *sv;
  259. sv = P(s);
  260. if(sv != H) {
  261. h = D2H(sv);
  262. h->ref++;
  263. Setmark(h);
  264. }
  265. dv = P(d);
  266. P(d) = sv;
  267. destroy(dv);
  268. }
  269. OP(movmp)
  270. {
  271. Type *t;
  272. t = R.M->type[W(m)];
  273. incmem(R.s, t);
  274. if (t->np)
  275. freeptrs(R.d, t);
  276. memmove(R.d, R.s, t->size);
  277. }
  278. OP(new)
  279. {
  280. Heap *h;
  281. WORD **wp, *t;
  282. h = heap(R.M->type[W(s)]);
  283. wp = R.d;
  284. t = *wp;
  285. *wp = H2D(WORD*, h);
  286. destroy(t);
  287. }
  288. OP(newz)
  289. {
  290. Heap *h;
  291. WORD **wp, *t;
  292. h = heapz(R.M->type[W(s)]);
  293. wp = R.d;
  294. t = *wp;
  295. *wp = H2D(WORD*, h);
  296. destroy(t);
  297. }
  298. OP(mnewz)
  299. {
  300. Heap *h;
  301. WORD **wp, *t;
  302. Modlink *ml;
  303. ml = *(Modlink**)R.s;
  304. if(ml == H)
  305. error(exModule);
  306. h = heapz(ml->type[W(m)]);
  307. wp = R.d;
  308. t = *wp;
  309. *wp = H2D(WORD*, h);
  310. destroy(t);
  311. }
  312. OP(frame)
  313. {
  314. Type *t;
  315. Frame *f;
  316. uchar *nsp;
  317. t = R.M->type[W(s)];
  318. nsp = R.SP + t->size;
  319. if(nsp >= R.TS) {
  320. R.s = t;
  321. extend();
  322. T(d) = R.s;
  323. return;
  324. }
  325. f = (Frame*)R.SP;
  326. R.SP = nsp;
  327. f->t = t;
  328. f->mr = nil;
  329. if (t->np)
  330. initmem(t, f);
  331. T(d) = f;
  332. }
  333. OP(mframe)
  334. {
  335. Type *t;
  336. Frame *f;
  337. uchar *nsp;
  338. Modlink *ml;
  339. int o;
  340. ml = *(Modlink**)R.s;
  341. if(ml == H)
  342. error(exModule);
  343. o = W(m);
  344. if(o >= 0){
  345. if(o >= ml->nlinks)
  346. error("invalid mframe");
  347. t = ml->links[o].frame;
  348. }
  349. else
  350. t = ml->m->ext[-o-1].frame;
  351. nsp = R.SP + t->size;
  352. if(nsp >= R.TS) {
  353. R.s = t;
  354. extend();
  355. T(d) = R.s;
  356. return;
  357. }
  358. f = (Frame*)R.SP;
  359. R.SP = nsp;
  360. f->t = t;
  361. f->mr = nil;
  362. if (t->np)
  363. initmem(t, f);
  364. T(d) = f;
  365. }
  366. void
  367. acheck(int tsz, int sz)
  368. {
  369. if(sz < 0)
  370. error(exNegsize);
  371. /* test for overflow; assumes sz >>> tsz */
  372. if((int)(sizeof(Array) + sizeof(Heap) + tsz*sz) < sz && tsz != 0)
  373. error(exHeap);
  374. }
  375. OP(newa)
  376. {
  377. int sz;
  378. Type *t;
  379. Heap *h;
  380. Array *a, *at, **ap;
  381. t = R.M->type[W(m)];
  382. sz = W(s);
  383. acheck(t->size, sz);
  384. h = nheap(sizeof(Array) + (t->size*sz));
  385. h->t = &Tarray;
  386. Tarray.ref++;
  387. a = H2D(Array*, h);
  388. a->t = t;
  389. a->len = sz;
  390. a->root = H;
  391. a->data = (uchar*)a + sizeof(Array);
  392. initarray(t, a);
  393. ap = R.d;
  394. at = *ap;
  395. *ap = a;
  396. destroy(at);
  397. }
  398. OP(newaz)
  399. {
  400. int sz;
  401. Type *t;
  402. Heap *h;
  403. Array *a, *at, **ap;
  404. t = R.M->type[W(m)];
  405. sz = W(s);
  406. acheck(t->size, sz);
  407. h = nheap(sizeof(Array) + (t->size*sz));
  408. h->t = &Tarray;
  409. Tarray.ref++;
  410. a = H2D(Array*, h);
  411. a->t = t;
  412. a->len = sz;
  413. a->root = H;
  414. a->data = (uchar*)a + sizeof(Array);
  415. memset(a->data, 0, t->size*sz);
  416. initarray(t, a);
  417. ap = R.d;
  418. at = *ap;
  419. *ap = a;
  420. destroy(at);
  421. }
  422. Channel*
  423. cnewc(Type *t, void (*mover)(void), int len)
  424. {
  425. Heap *h;
  426. Channel *c;
  427. h = heap(&Tchannel);
  428. c = H2D(Channel*, h);
  429. c->send = malloc(sizeof(Progq));
  430. c->recv = malloc(sizeof(Progq));
  431. if(c->send == nil || c->recv == nil){
  432. free(c->send);
  433. free(c->recv);
  434. error(exNomem);
  435. }
  436. c->send->prog = c->recv->prog = nil;
  437. c->send->next = c->recv->next = nil;
  438. c->mover = mover;
  439. c->buf = H;
  440. if(len > 0)
  441. c->buf = H2D(Array*, heaparray(t, len));
  442. c->front = 0;
  443. c->size = 0;
  444. if(mover == movtmp){
  445. c->mid.t = t;
  446. t->ref++;
  447. }
  448. return c;
  449. }
  450. Channel*
  451. newc(Type *t, void (*mover)(void))
  452. {
  453. Channel **cp, *oldc;
  454. WORD len;
  455. len = 0;
  456. if(R.m != R.d){
  457. len = W(m);
  458. if(len < 0)
  459. error(exNegsize);
  460. }
  461. cp = R.d;
  462. oldc = *cp;
  463. *cp = cnewc(t, mover, len);
  464. destroy(oldc);
  465. return *cp;
  466. }
  467. OP(newcl) { newc(&Tlong, movl); }
  468. OP(newcb) { newc(&Tbyte, movb); }
  469. OP(newcw) { newc(&Tword, movw); }
  470. OP(newcf) { newc(&Treal, movf); }
  471. OP(newcp) { newc(&Tptr, movp); }
  472. OP(newcm)
  473. {
  474. Channel *c;
  475. Type *t;
  476. t = nil;
  477. if(R.m != R.d && W(m) > 0)
  478. t = dtype(nil, W(s), nil, 0);
  479. c = newc(t, movm);
  480. c->mid.w = W(s);
  481. if(t != nil)
  482. freetype(t);
  483. }
  484. OP(newcmp)
  485. {
  486. newc(R.M->type[W(s)], movtmp);
  487. }
  488. OP(icase)
  489. {
  490. WORD v, *t, *l, d, n, n2;
  491. v = W(s);
  492. t = (WORD*)((WORD)R.d + IBY2WD);
  493. n = t[-1];
  494. d = t[n*3];
  495. while(n > 0) {
  496. n2 = n >> 1;
  497. l = t + n2*3;
  498. if(v < l[0]) {
  499. n = n2;
  500. continue;
  501. }
  502. if(v >= l[1]) {
  503. t = l+3;
  504. n -= n2 + 1;
  505. continue;
  506. }
  507. d = l[2];
  508. break;
  509. }
  510. if(R.M->compiled) {
  511. R.PC = (Inst*)d;
  512. return;
  513. }
  514. R.PC = R.M->prog + d;
  515. }
  516. OP(casel)
  517. {
  518. WORD *t, *l, d, n, n2;
  519. LONG v;
  520. v = V(s);
  521. t = (WORD*)((WORD)R.d + 2*IBY2WD);
  522. n = t[-2];
  523. d = t[n*6];
  524. while(n > 0) {
  525. n2 = n >> 1;
  526. l = t + n2*6;
  527. if(v < ((LONG*)l)[0]) {
  528. n = n2;
  529. continue;
  530. }
  531. if(v >= ((LONG*)l)[1]) {
  532. t = l+6;
  533. n -= n2 + 1;
  534. continue;
  535. }
  536. d = l[4];
  537. break;
  538. }
  539. if(R.M->compiled) {
  540. R.PC = (Inst*)d;
  541. return;
  542. }
  543. R.PC = R.M->prog + d;
  544. }
  545. OP(casec)
  546. {
  547. WORD *l, *t, *e, n, n2, r;
  548. String *sl, *sh, *sv;
  549. sv = S(s);
  550. t = (WORD*)((WORD)R.d + IBY2WD);
  551. n = t[-1];
  552. e = t + n*3;
  553. if(n > 2){
  554. while(n > 0){
  555. n2 = n>>1;
  556. l = t + n2*3;
  557. sl = (String*)l[0];
  558. r = stringcmp(sv, sl);
  559. if(r == 0){
  560. e = &l[2];
  561. break;
  562. }
  563. if(r < 0){
  564. n = n2;
  565. continue;
  566. }
  567. sh = (String*)l[1];
  568. if(sh == H || stringcmp(sv, sh) > 0){
  569. t = l+3;
  570. n -= n2+1;
  571. continue;
  572. }
  573. e = &l[2];
  574. break;
  575. }
  576. t = e;
  577. }
  578. else{
  579. while(t < e) {
  580. sl = (String*)t[0];
  581. sh = (String*)t[1];
  582. if(sh == H) {
  583. if(stringcmp(sl, sv) == 0) {
  584. t = &t[2];
  585. goto found;
  586. }
  587. }
  588. else
  589. if(stringcmp(sl, sv) <= 0 && stringcmp(sh, sv) >= 0) {
  590. t = &t[2];
  591. goto found;
  592. }
  593. t += 3;
  594. }
  595. }
  596. found:
  597. if(R.M->compiled) {
  598. R.PC = (Inst*)*t;
  599. return;
  600. }
  601. R.PC = R.M->prog + t[0];
  602. }
  603. OP(igoto)
  604. {
  605. WORD *t;
  606. t = (WORD*)((WORD)R.d + (W(s) * IBY2WD));
  607. if(R.M->compiled) {
  608. R.PC = (Inst*)t[0];
  609. return;
  610. }
  611. R.PC = R.M->prog + t[0];
  612. }
  613. OP(call)
  614. {
  615. Frame *f;
  616. f = T(s);
  617. f->lr = R.PC;
  618. f->fp = R.FP;
  619. R.FP = (uchar*)f;
  620. JMP(d);
  621. }
  622. OP(spawn)
  623. {
  624. Prog *p;
  625. p = newprog(currun(), R.M);
  626. p->R.PC = *(Inst**)R.d;
  627. newstack(p);
  628. unframe();
  629. }
  630. OP(mspawn)
  631. {
  632. Prog *p;
  633. Modlink *ml;
  634. int o;
  635. ml = *(Modlink**)R.d;
  636. if(ml == H)
  637. error(exModule);
  638. if(ml->prog == nil)
  639. error(exSpawn);
  640. p = newprog(currun(), ml);
  641. o = W(m);
  642. if(o >= 0)
  643. p->R.PC = ml->links[o].u.pc;
  644. else
  645. p->R.PC = ml->m->ext[-o-1].u.pc;
  646. newstack(p);
  647. unframe();
  648. }
  649. OP(ret)
  650. {
  651. Frame *f;
  652. Modlink *m;
  653. f = (Frame*)R.FP;
  654. R.FP = f->fp;
  655. if(R.FP == nil) {
  656. R.FP = (uchar*)f;
  657. error("");
  658. }
  659. R.SP = (uchar*)f;
  660. R.PC = f->lr;
  661. m = f->mr;
  662. if(f->t == nil)
  663. unextend(f);
  664. else if (f->t->np)
  665. freeptrs(f, f->t);
  666. if(m != nil) {
  667. if(R.M->compiled != m->compiled) {
  668. R.IC = 1;
  669. R.t = 1;
  670. }
  671. destroy(R.M);
  672. R.M = m;
  673. R.MP = m->MP;
  674. }
  675. }
  676. OP(iload)
  677. {
  678. char *n;
  679. Import *ldt;
  680. Module *m;
  681. Modlink *ml, **mp, *t;
  682. Heap *h;
  683. n = string2c(S(s));
  684. m = R.M->m;
  685. if(m->rt & HASLDT)
  686. ldt = m->ldt[W(m)];
  687. else{
  688. ldt = nil;
  689. error("obsolete dis");
  690. }
  691. if(strcmp(n, "$self") == 0) {
  692. m->ref++;
  693. ml = linkmod(m, ldt, 0);
  694. if(ml != H) {
  695. ml->MP = R.M->MP;
  696. h = D2H(ml->MP);
  697. h->ref++;
  698. Setmark(h);
  699. }
  700. }
  701. else {
  702. m = readmod(n, lookmod(n), 1);
  703. ml = linkmod(m, ldt, 1);
  704. }
  705. mp = R.d;
  706. t = *mp;
  707. *mp = ml;
  708. destroy(t);
  709. }
  710. OP(mcall)
  711. {
  712. Heap *h;
  713. Prog *p;
  714. Frame *f;
  715. Linkpc *l;
  716. Modlink *ml;
  717. int o;
  718. ml = *(Modlink**)R.d;
  719. if(ml == H)
  720. error(exModule);
  721. f = T(s);
  722. f->lr = R.PC;
  723. f->fp = R.FP;
  724. f->mr = R.M;
  725. R.FP = (uchar*)f;
  726. R.M = ml;
  727. h = D2H(ml);
  728. h->ref++;
  729. o = W(m);
  730. if(o >= 0)
  731. l = &ml->links[o].u;
  732. else
  733. l = &ml->m->ext[-o-1].u;
  734. if(ml->prog == nil) {
  735. l->runt(f);
  736. h->ref--;
  737. R.M = f->mr;
  738. R.SP = R.FP;
  739. R.FP = f->fp;
  740. if(f->t == nil)
  741. unextend(f);
  742. else if (f->t->np)
  743. freeptrs(f, f->t);
  744. p = currun();
  745. if(p->kill != nil)
  746. error(p->kill);
  747. R.t = 0;
  748. return;
  749. }
  750. R.MP = R.M->MP;
  751. R.PC = l->pc;
  752. R.t = 1;
  753. if(f->mr->compiled != R.M->compiled)
  754. R.IC = 1;
  755. }
  756. OP(lena)
  757. {
  758. WORD l;
  759. Array *a;
  760. a = A(s);
  761. l = 0;
  762. if(a != H)
  763. l = a->len;
  764. W(d) = l;
  765. }
  766. OP(lenl)
  767. {
  768. WORD l;
  769. List *a;
  770. a = L(s);
  771. l = 0;
  772. while(a != H) {
  773. l++;
  774. a = a->tail;
  775. }
  776. W(d) = l;
  777. }
  778. static int
  779. cgetb(Channel *c, void *v)
  780. {
  781. Array *a;
  782. void *w;
  783. if((a = c->buf) == H)
  784. return 0;
  785. if(c->size > 0){
  786. w = a->data+c->front*a->t->size;
  787. c->front++;
  788. if(c->front == c->buf->len)
  789. c->front = 0;
  790. c->size--;
  791. R.s = w;
  792. R.m = &c->mid;
  793. R.d = v;
  794. c->mover();
  795. if(a->t->np){
  796. freeptrs(w, a->t);
  797. initmem(a->t, w);
  798. }
  799. return 1;
  800. }
  801. return 0;
  802. }
  803. static int
  804. cputb(Channel *c, void *v)
  805. {
  806. Array *a;
  807. WORD len, r;
  808. if((a = c->buf) == H)
  809. return 0;
  810. len = c->buf->len;
  811. if(c->size < len){
  812. r = c->front+c->size;
  813. if(r >= len)
  814. r -= len;
  815. c->size++;
  816. R.s = v;
  817. R.m = &c->mid;
  818. R.d = a->data+r*a->t->size;
  819. c->mover();
  820. return 1;
  821. }
  822. return 0;
  823. }
  824. /*
  825. int
  826. cqsize(Progq *q)
  827. {
  828. int n;
  829. n = 0;
  830. for( ; q != nil; q = q->next)
  831. if(q->prog != nil)
  832. n++;
  833. return n;
  834. }
  835. */
  836. void
  837. cqadd(Progq **q, Prog *p)
  838. {
  839. Progq *n;
  840. if((*q)->prog == nil){
  841. (*q)->prog = p;
  842. return;
  843. }
  844. n = (Progq*)malloc(sizeof(Progq));
  845. if(n == nil)
  846. error(exNomem);
  847. n->prog = p;
  848. n->next = nil;
  849. for( ; *q != nil; q = &(*q)->next)
  850. ;
  851. *q = n;
  852. }
  853. void
  854. cqdel(Progq **q)
  855. {
  856. Progq *f;
  857. if((*q)->next == nil){
  858. (*q)->prog = nil;
  859. return;
  860. }
  861. f = *q;
  862. *q = f->next;
  863. free(f);
  864. }
  865. void
  866. cqdelp(Progq **q, Prog *p)
  867. {
  868. Progq *f;
  869. if((*q)->next == nil){
  870. if((*q)->prog == p)
  871. (*q)->prog = nil;
  872. return;
  873. }
  874. for( ; *q != nil; ){
  875. if((*q)->prog == p){
  876. f = *q;
  877. *q = (*q)->next;
  878. free(f);
  879. }
  880. else
  881. q = &(*q)->next;
  882. }
  883. }
  884. OP(isend)
  885. {
  886. Channel *c;
  887. Prog *p;
  888. c = C(d);
  889. if(c == H)
  890. error(exNilref);
  891. if((p = c->recv->prog) == nil) {
  892. if(c->buf != H && cputb(c, R.s))
  893. return;
  894. p = delrun(Psend);
  895. p->ptr = R.s;
  896. p->chan = c; /* for killprog */
  897. R.IC = 1;
  898. R.t = 1;
  899. cqadd(&c->send, p);
  900. return;
  901. }
  902. if(c->buf != H && c->size > 0)
  903. print("non-empty buffer in isend\n");
  904. cqdel(&c->recv);
  905. if(p->state == Palt)
  906. altdone(p->R.s, p, c, 1);
  907. R.m = &c->mid;
  908. R.d = p->ptr;
  909. p->ptr = nil;
  910. c->mover();
  911. addrun(p);
  912. R.t = 0;
  913. }
  914. OP(irecv)
  915. {
  916. Channel *c;
  917. Prog *p;
  918. c = C(s);
  919. if(c == H)
  920. error(exNilref);
  921. if((p = c->send->prog) == nil) {
  922. if(c->buf != H && cgetb(c, R.d))
  923. return;
  924. p = delrun(Precv);
  925. p->ptr = R.d;
  926. p->chan = c; /* for killprog */
  927. R.IC = 1;
  928. R.t = 1;
  929. cqadd(&c->recv, p);
  930. return;
  931. }
  932. if(c->buf != H && c->size != c->buf->len)
  933. print("non-full buffer in irecv\n");
  934. cqdel(&c->send);
  935. if(p->state == Palt)
  936. altdone(p->R.s, p, c, 0);
  937. if(c->buf != H){
  938. cgetb(c, R.d);
  939. cputb(c, p->ptr);
  940. p->ptr = nil;
  941. }
  942. else{
  943. R.m = &c->mid;
  944. R.s = p->ptr;
  945. p->ptr = nil;
  946. c->mover();
  947. }
  948. addrun(p);
  949. R.t = 0;
  950. }
  951. int
  952. csendalt(Channel *c, void *ip, Type *t, int len)
  953. {
  954. REG rsav;
  955. if(c == H)
  956. error(exNilref);
  957. if(c->recv->prog == nil && (c->buf == H || c->size == c->buf->len)){
  958. if(c->buf != H){
  959. print("csendalt failed\n");
  960. freeptrs(ip, t);
  961. return 0;
  962. }
  963. c->buf = H2D(Array*, heaparray(t, len));
  964. }
  965. rsav = R;
  966. R.s = ip;
  967. R.d = &c;
  968. isend();
  969. R = rsav;
  970. freeptrs(ip, t);
  971. return 1;
  972. }
  973. List*
  974. cons(ulong size, List **lp)
  975. {
  976. Heap *h;
  977. List *lv, *l;
  978. h = nheap(sizeof(List) + size - sizeof(((List*)0)->data));
  979. h->t = &Tlist;
  980. Tlist.ref++;
  981. l = H2D(List*, h);
  982. l->t = nil;
  983. lv = *lp;
  984. if(lv != H) {
  985. h = D2H(lv);
  986. Setmark(h);
  987. }
  988. l->tail = lv;
  989. *lp = l;
  990. return l;
  991. }
  992. OP(consb)
  993. {
  994. List *l;
  995. l = cons(IBY2WD, R.d);
  996. *(BYTE*)l->data = B(s);
  997. }
  998. OP(consw)
  999. {
  1000. List *l;
  1001. l = cons(IBY2WD, R.d);
  1002. *(WORD*)l->data = W(s);
  1003. }
  1004. OP(consl)
  1005. {
  1006. List *l;
  1007. l = cons(IBY2LG, R.d);
  1008. *(LONG*)l->data = V(s);
  1009. }
  1010. OP(consp)
  1011. {
  1012. List *l;
  1013. Heap *h;
  1014. WORD *sv;
  1015. l = cons(IBY2WD, R.d);
  1016. sv = P(s);
  1017. if(sv != H) {
  1018. h = D2H(sv);
  1019. h->ref++;
  1020. Setmark(h);
  1021. }
  1022. l->t = &Tptr;
  1023. Tptr.ref++;
  1024. *(WORD**)l->data = sv;
  1025. }
  1026. OP(consf)
  1027. {
  1028. List *l;
  1029. l = cons(sizeof(REAL), R.d);
  1030. *(REAL*)l->data = F(s);
  1031. }
  1032. OP(consm)
  1033. {
  1034. int v;
  1035. List *l;
  1036. v = W(m);
  1037. l = cons(v, R.d);
  1038. memmove(l->data, R.s, v);
  1039. }
  1040. OP(consmp)
  1041. {
  1042. List *l;
  1043. Type *t;
  1044. t = R.M->type[W(m)];
  1045. l = cons(t->size, R.d);
  1046. incmem(R.s, t);
  1047. memmove(l->data, R.s, t->size);
  1048. l->t = t;
  1049. t->ref++;
  1050. }
  1051. OP(headb)
  1052. {
  1053. List *l;
  1054. l = L(s);
  1055. B(d) = *(BYTE*)l->data;
  1056. }
  1057. OP(headw)
  1058. {
  1059. List *l;
  1060. l = L(s);
  1061. W(d) = *(WORD*)l->data;
  1062. }
  1063. OP(headl)
  1064. {
  1065. List *l;
  1066. l = L(s);
  1067. V(d) = *(LONG*)l->data;
  1068. }
  1069. OP(headp)
  1070. {
  1071. List *l;
  1072. l = L(s);
  1073. R.s = l->data;
  1074. movp();
  1075. }
  1076. OP(headf)
  1077. {
  1078. List *l;
  1079. l = L(s);
  1080. F(d) = *(REAL*)l->data;
  1081. }
  1082. OP(headm)
  1083. {
  1084. List *l;
  1085. l = L(s);
  1086. memmove(R.d, l->data, W(m));
  1087. }
  1088. OP(headmp)
  1089. {
  1090. List *l;
  1091. l = L(s);
  1092. R.s = l->data;
  1093. movmp();
  1094. }
  1095. OP(tail)
  1096. {
  1097. List *l;
  1098. l = L(s);
  1099. R.s = &l->tail;
  1100. movp();
  1101. }
  1102. OP(slicea)
  1103. {
  1104. Type *t;
  1105. Heap *h;
  1106. Array *at, *ss, *ds;
  1107. int v, n, start;
  1108. v = W(m);
  1109. start = W(s);
  1110. n = v - start;
  1111. ds = A(d);
  1112. if(ds == H) {
  1113. if(n == 0)
  1114. return;
  1115. error(exNilref);
  1116. }
  1117. if(n < 0 || (ulong)start > ds->len || (ulong)v > ds->len)
  1118. error(exBounds);
  1119. t = ds->t;
  1120. h = heap(&Tarray);
  1121. ss = H2D(Array*, h);
  1122. ss->len = n;
  1123. ss->data = ds->data + start*t->size;
  1124. ss->t = t;
  1125. t->ref++;
  1126. if(ds->root != H) { /* slicing a slice */
  1127. ds = ds->root;
  1128. h = D2H(ds);
  1129. h->ref++;
  1130. at = A(d);
  1131. A(d) = ss;
  1132. ss->root = ds;
  1133. destroy(at);
  1134. }
  1135. else {
  1136. h = D2H(ds);
  1137. ss->root = ds;
  1138. A(d) = ss;
  1139. }
  1140. Setmark(h);
  1141. }
  1142. OP(slicela)
  1143. {
  1144. Type *t;
  1145. int l, dl;
  1146. Array *ss, *ds;
  1147. uchar *sp, *dp, *ep;
  1148. ss = A(s);
  1149. dl = W(m);
  1150. ds = A(d);
  1151. if(ss == H)
  1152. return;
  1153. if(ds == H)
  1154. error(exNilref);
  1155. if(dl < 0 || dl+ss->len > ds->len)
  1156. error(exBounds);
  1157. t = ds->t;
  1158. if(t->np == 0) {
  1159. memmove(ds->data+dl*t->size, ss->data, ss->len*t->size);
  1160. return;
  1161. }
  1162. sp = ss->data;
  1163. dp = ds->data+dl*t->size;
  1164. if(dp > sp) {
  1165. l = ss->len * t->size;
  1166. sp = ss->data + l;
  1167. ep = dp + l;
  1168. while(ep > dp) {
  1169. ep -= t->size;
  1170. sp -= t->size;
  1171. incmem(sp, t);
  1172. if (t->np)
  1173. freeptrs(ep, t);
  1174. }
  1175. }
  1176. else {
  1177. ep = dp + ss->len*t->size;
  1178. while(dp < ep) {
  1179. incmem(sp, t);
  1180. if (t->np)
  1181. freeptrs(dp, t);
  1182. dp += t->size;
  1183. sp += t->size;
  1184. }
  1185. }
  1186. memmove(ds->data+dl*t->size, ss->data, ss->len*t->size);
  1187. }
  1188. OP(alt)
  1189. {
  1190. R.t = 0;
  1191. xecalt(1);
  1192. }
  1193. OP(nbalt)
  1194. {
  1195. xecalt(0);
  1196. }
  1197. OP(tcmp)
  1198. {
  1199. void *s, *d;
  1200. s = T(s);
  1201. d = T(d);
  1202. if(s != H && (d == H || D2H(s)->t != D2H(d)->t))
  1203. error(exTcheck);
  1204. }
  1205. OP(eclr)
  1206. {
  1207. /* spare slot */
  1208. }
  1209. OP(badop)
  1210. {
  1211. error(exOp);
  1212. }
  1213. OP(iraise)
  1214. {
  1215. void *v;
  1216. Heap *h;
  1217. Prog *p;
  1218. p = currun();
  1219. v = T(s);
  1220. if(v == H)
  1221. error(exNilref);
  1222. p->exval = v;
  1223. h = D2H(v);
  1224. h->ref++;
  1225. if(h->t == &Tstring)
  1226. error(string2c((String*)v));
  1227. else
  1228. error(string2c(*(String**)v));
  1229. }
  1230. OP(mulx)
  1231. {
  1232. WORD p;
  1233. LONG r;
  1234. p = Dtmp;
  1235. r = (LONG)W(m)*(LONG)W(s);
  1236. if(p >= 0)
  1237. r <<= p;
  1238. else
  1239. r >>= (-p);
  1240. W(d) = (WORD)r;
  1241. }
  1242. OP(divx)
  1243. {
  1244. WORD p;
  1245. LONG s;
  1246. p = Dtmp;
  1247. s = (LONG)W(m);
  1248. if(p >= 0)
  1249. s <<= p;
  1250. else
  1251. s >>= (-p);
  1252. s /= (LONG)W(s);
  1253. W(d) = (WORD)s;
  1254. }
  1255. OP(cvtxx)
  1256. {
  1257. WORD p;
  1258. LONG r;
  1259. p = W(m);
  1260. r = (LONG)W(s);
  1261. if(p >= 0)
  1262. r <<= p;
  1263. else
  1264. r >>= (-p);
  1265. W(d) = (WORD)r;
  1266. }
  1267. OP(mulx0)
  1268. {
  1269. WORD x, y, p, a;
  1270. LONG r;
  1271. x = W(m);
  1272. y = W(s);
  1273. p = Dtmp;
  1274. a = Stmp;
  1275. if(x == 0 || y == 0){
  1276. W(d) = 0;
  1277. return;
  1278. }
  1279. r = (LONG)x*(LONG)y;
  1280. if(p >= 0)
  1281. r <<= p;
  1282. else
  1283. r >>= (-p);
  1284. r /= (LONG)a;
  1285. W(d) = (WORD)r;
  1286. }
  1287. OP(divx0)
  1288. {
  1289. WORD x, y, p, b;
  1290. LONG s;
  1291. x = W(m);
  1292. y = W(s);
  1293. p = Dtmp;
  1294. b = Stmp;
  1295. if(x == 0){
  1296. W(d) = 0;
  1297. return;
  1298. }
  1299. s = (LONG)b*(LONG)x;
  1300. if(p >= 0)
  1301. s <<= p;
  1302. else
  1303. s >>= (-p);
  1304. s /= (LONG)y;
  1305. W(d) = (WORD)s;
  1306. }
  1307. OP(cvtxx0)
  1308. {
  1309. WORD x, p, a;
  1310. LONG r;
  1311. x = W(s);
  1312. p = W(m);
  1313. a = Stmp;
  1314. if(x == 0){
  1315. W(d) = 0;
  1316. return;
  1317. }
  1318. r = (LONG)x;
  1319. if(p >= 0)
  1320. r <<= p;
  1321. else
  1322. r >>= (-p);
  1323. r /= (LONG)a;
  1324. W(d) = (WORD)r;
  1325. }
  1326. OP(mulx1)
  1327. {
  1328. WORD x, y, p, a, v;
  1329. int vnz, wnz;
  1330. LONG w, r;
  1331. x = W(m);
  1332. y = W(s);
  1333. p = Dtmp;
  1334. a = Stmp;
  1335. if(x == 0 || y == 0){
  1336. W(d) = 0;
  1337. return;
  1338. }
  1339. vnz = p&2;
  1340. wnz = p&1;
  1341. p >>= 2;
  1342. v = 0;
  1343. w = 0;
  1344. if(vnz){
  1345. v = a-1;
  1346. if(x >= 0 && y < 0 || x < 0 && y >= 0)
  1347. v = -v;
  1348. }
  1349. if(wnz){
  1350. if((!vnz && (x > 0 && y < 0 || x < 0 && y > 0)) ||
  1351. (vnz && (x > 0 && y > 0 || x < 0 && y < 0)))
  1352. w = ((LONG)1<<(-p)) - 1;
  1353. }
  1354. r = (LONG)x*(LONG)y + w;
  1355. if(p >= 0)
  1356. r <<= p;
  1357. else
  1358. r >>= (-p);
  1359. r += (LONG)v;
  1360. r /= (LONG)a;
  1361. W(d) = (WORD)r;
  1362. }
  1363. OP(divx1)
  1364. {
  1365. WORD x, y, p, b, v;
  1366. int vnz, wnz;
  1367. LONG w, s;
  1368. x = W(m);
  1369. y = W(s);
  1370. p = Dtmp;
  1371. b = Stmp;
  1372. if(x == 0){
  1373. W(d) = 0;
  1374. return;
  1375. }
  1376. vnz = p&2;
  1377. wnz = p&1;
  1378. p >>= 2;
  1379. v = 0;
  1380. w = 0;
  1381. if(vnz){
  1382. v = 1;
  1383. if(x >= 0 && y < 0 || x < 0 && y >= 0)
  1384. v = -v;
  1385. }
  1386. if(wnz){
  1387. if(x <= 0)
  1388. w = ((LONG)1<<(-p)) - 1;
  1389. }
  1390. s = (LONG)b*(LONG)x + w;
  1391. if(p >= 0)
  1392. s <<= p;
  1393. else
  1394. s >>= (-p);
  1395. s /= (LONG)y;
  1396. W(d) = (WORD)s + v;
  1397. }
  1398. OP(cvtxx1)
  1399. {
  1400. WORD x, p, a, v;
  1401. int vnz, wnz;
  1402. LONG w, r;
  1403. x = W(s);
  1404. p = W(m);
  1405. a = Stmp;
  1406. if(x == 0){
  1407. W(d) = 0;
  1408. return;
  1409. }
  1410. vnz = p&2;
  1411. wnz = p&1;
  1412. p >>= 2;
  1413. v = 0;
  1414. w = 0;
  1415. if(vnz){
  1416. v = a-1;
  1417. if(x < 0)
  1418. v = -v;
  1419. }
  1420. if(wnz){
  1421. if(!vnz && x < 0 || vnz && x > 0)
  1422. w = ((LONG)1<<(-p)) - 1;
  1423. }
  1424. r = (LONG)x + w;
  1425. if(p >= 0)
  1426. r <<= p;
  1427. else
  1428. r >>= (-p);
  1429. r += (LONG)v;
  1430. r /= (LONG)a;
  1431. W(d) = (WORD)r;
  1432. }
  1433. /*
  1434. OP(cvtxx)
  1435. {
  1436. REAL v;
  1437. v = (REAL)W(s)*F(m);
  1438. v = v < 0 ? v-0.5: v+0.5;
  1439. W(d) = (WORD)v;
  1440. }
  1441. */
  1442. OP(cvtfx)
  1443. {
  1444. REAL v;
  1445. v = F(s)*F(m);
  1446. v = v < 0 ? v-0.5: v+0.5;
  1447. W(d) = (WORD)v;
  1448. }
  1449. OP(cvtxf)
  1450. {
  1451. F(d) = (REAL)W(s)*F(m);
  1452. }
  1453. OP(self)
  1454. {
  1455. Modlink *ml, **mp, *t;
  1456. Heap *h;
  1457. ml = R.M;
  1458. h = D2H(ml);
  1459. h->ref++;
  1460. Setmark(h);
  1461. mp = R.d;
  1462. t = *mp;
  1463. *mp = ml;
  1464. destroy(t);
  1465. }
  1466. void
  1467. destroystack(REG *reg)
  1468. {
  1469. Type *t;
  1470. Frame *f, *fp;
  1471. Modlink *m;
  1472. Stkext *sx;
  1473. uchar *ex;
  1474. ex = reg->EX;
  1475. reg->EX = nil;
  1476. while(ex != nil) {
  1477. sx = (Stkext*)ex;
  1478. fp = sx->reg.tos.fr;
  1479. do {
  1480. f = (Frame*)reg->FP;
  1481. if(f == nil)
  1482. break;
  1483. reg->FP = f->fp;
  1484. t = f->t;
  1485. if(t == nil)
  1486. t = sx->reg.TR;
  1487. m = f->mr;
  1488. if (t->np)
  1489. freeptrs(f, t);
  1490. if(m != nil) {
  1491. destroy(reg->M);
  1492. reg->M = m;
  1493. }
  1494. } while(f != fp);
  1495. ex = sx->reg.EX;
  1496. free(sx);
  1497. }
  1498. destroy(reg->M);
  1499. reg->M = H; /* for devprof */
  1500. }
  1501. Prog*
  1502. isave(void)
  1503. {
  1504. Prog *p;
  1505. p = delrun(Prelease);
  1506. p->R = R;
  1507. return p;
  1508. }
  1509. void
  1510. irestore(Prog *p)
  1511. {
  1512. R = p->R;
  1513. R.IC = 1;
  1514. }
  1515. void
  1516. movtmp(void) /* Used by send & receive */
  1517. {
  1518. Type *t;
  1519. t = (Type*)W(m);
  1520. incmem(R.s, t);
  1521. if (t->np)
  1522. freeptrs(R.d, t);
  1523. memmove(R.d, R.s, t->size);
  1524. }
  1525. extern OP(cvtca);
  1526. extern OP(cvtac);
  1527. extern OP(cvtwc);
  1528. extern OP(cvtcw);
  1529. extern OP(cvtfc);
  1530. extern OP(cvtcf);
  1531. extern OP(insc);
  1532. extern OP(indc);
  1533. extern OP(addc);
  1534. extern OP(lenc);
  1535. extern OP(slicec);
  1536. extern OP(cvtlc);
  1537. #include "optab.h"
  1538. void
  1539. opinit(void)
  1540. {
  1541. int i;
  1542. for(i = 0; i < 256; i++)
  1543. if(optab[i] == nil)
  1544. optab[i] = badop;
  1545. }
  1546. void
  1547. xec(Prog *p)
  1548. {
  1549. int op;
  1550. R = p->R;
  1551. R.MP = R.M->MP;
  1552. R.IC = p->quanta;
  1553. if(p->kill != nil) {
  1554. char *m;
  1555. m = p->kill;
  1556. p->kill = nil;
  1557. error(m);
  1558. }
  1559. // print("%lux %lux %lux %lux %lux\n", (ulong)&R, R.xpc, R.FP, R.MP, R.PC);
  1560. if(R.M->compiled)
  1561. comvec();
  1562. else do {
  1563. dec[R.PC->add]();
  1564. op = R.PC->op;
  1565. R.PC++;
  1566. optab[op]();
  1567. } while(--R.IC != 0);
  1568. p->R = R;
  1569. }