1
1

simulator.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. #include "simulator.h"
  2. Simulator::Simulator() {
  3. programs.reserve(FIELDS_XY * FIELDS_XY);
  4. // std::srand(std::time(0));
  5. std::srand(0);
  6. }
  7. Position Simulator::calcPosition(Position position, Direction direction, int32_t distance) {
  8. switch(direction) {
  9. case Right: return Position{(position.x + distance) % FIELDS_XY, position.y};
  10. case Down: return Position{position.x, (position.y + distance) % FIELDS_XY};
  11. case Left: return Position{(position.x - distance) % FIELDS_XY, position.y};
  12. case Up: return Position{position.x, (position.y - distance) % FIELDS_XY};
  13. }
  14. }
  15. void Simulator::decode(Program& program, Task& task, int& v, int*& var_v, int param) {
  16. var_v = nullptr;
  17. switch(param) {
  18. case Local_1 : v = program.vars[0]; var_v = &program.vars[0]; break;
  19. case Local_2 : v = program.vars[1]; var_v = &program.vars[1]; break;
  20. case Local_3 : v = program.vars[2]; var_v = &program.vars[2]; break;
  21. case Local_4 : v = program.vars[3]; var_v = &program.vars[3]; break;
  22. case Local_5 : v = program.vars[4]; var_v = &program.vars[4]; break;
  23. case Local_6 : v = program.vars[5]; var_v = &program.vars[5]; break;
  24. case Local_7 : v = program.vars[6]; var_v = &program.vars[6]; break;
  25. case Local_8 : v = program.vars[7]; var_v = &program.vars[7]; break;
  26. case Local_9 : v = program.vars[8]; var_v = &program.vars[8]; break;
  27. case Local_10: v = program.vars[9]; var_v = &program.vars[9]; break;
  28. case Local_11: v = program.vars[10]; var_v = &program.vars[10]; break;
  29. case Local_12: v = program.vars[11]; var_v = &program.vars[11]; break;
  30. case Local_13: v = program.vars[12]; var_v = &program.vars[12]; break;
  31. case Local_14: v = program.vars[13]; var_v = &program.vars[13]; break;
  32. case Local_15: v = program.vars[14]; var_v = &program.vars[14]; break;
  33. case Local_16: v = program.vars[15]; var_v = &program.vars[15]; break;
  34. case Local_17: v = program.vars[16]; var_v = &program.vars[16]; break;
  35. case Local_18: v = program.vars[17]; var_v = &program.vars[17]; break;
  36. case Local_19: v = program.vars[18]; var_v = &program.vars[18]; break;
  37. case Local_20: v = program.vars[19]; var_v = &program.vars[19]; break;
  38. case LocalActive:
  39. v = program.active;
  40. var_v = &program.active;
  41. break;
  42. case LocalBanks:
  43. v = program.banks.size();
  44. break;
  45. case LocalInstrSet:
  46. v = program.instructionSet;
  47. break;
  48. case LocalMobile:
  49. v = program.mobile;
  50. break;
  51. case LocalAge:
  52. v = cycle - program.creationCycle;
  53. break;
  54. case LocalTasks:
  55. v = program.tasks.size();
  56. break;
  57. case LocalGeneration:
  58. v = program.generation;
  59. break;
  60. case LocalId:
  61. v = program.team->id;
  62. break;
  63. case RemoteActive: {
  64. auto remotePosition = calcPosition(program.position, task.direction, 1);
  65. auto remoteProgram = findProgram(remotePosition);
  66. if(remoteProgram) {
  67. v = remoteProgram->active;
  68. var_v = &remoteProgram->active;
  69. }
  70. else {
  71. v = 0;
  72. var_v = nullptr;
  73. }
  74. break;
  75. }
  76. case RemoteBanks: {
  77. auto remotePosition = calcPosition(program.position, task.direction, 1);
  78. auto remoteProgram = findProgram(remotePosition);
  79. v = remoteProgram ? remoteProgram->banks.size() : 0;
  80. break;
  81. }
  82. case RemoteInstrSet: {
  83. auto remotePosition = calcPosition(program.position, task.direction, 1);
  84. auto remoteProgram = findProgram(remotePosition);
  85. v = remoteProgram ? remoteProgram->instructionSet : 0;
  86. break;
  87. }
  88. case RemoteMobile: {
  89. auto remotePosition = calcPosition(program.position, task.direction, 1);
  90. auto remoteProgram = findProgram(remotePosition);
  91. v = remoteProgram ? remoteProgram->mobile: 0;
  92. break;
  93. }
  94. case RemoteAge: {
  95. auto remotePosition = calcPosition(program.position, task.direction, 1);
  96. auto remoteProgram = findProgram(remotePosition);
  97. v = remoteProgram ? (cycle - remoteProgram->creationCycle) : 0;
  98. break;
  99. }
  100. case RemoteTasks: {
  101. auto remotePosition = calcPosition(program.position, task.direction, 1);
  102. auto remoteProgram = findProgram(remotePosition);
  103. v = remoteProgram ? remoteProgram->tasks.size() : 0;
  104. break;
  105. }
  106. case RemoteGeneration: {
  107. auto remotePosition = calcPosition(program.position, task.direction, 1);
  108. auto remoteProgram = findProgram(remotePosition);
  109. v = remoteProgram ? remoteProgram->generation : 0;
  110. break;
  111. }
  112. case GlobalPub:
  113. v = pub;
  114. var_v = &pub;
  115. break;
  116. case GlobalTeam:
  117. v = program.team->var;
  118. var_v = &program.team->var;
  119. break;
  120. case GlobalOwn:
  121. v = program.team->programCount;
  122. break;
  123. case GlobalOthers:
  124. v = 0;
  125. for(auto& team : teams) {
  126. if(team != program.team) {
  127. v += team->programCount;
  128. }
  129. }
  130. break;
  131. case GlobalFields:
  132. v = FIELDS_XY * FIELDS_XY;
  133. break;
  134. case GlobalTime:
  135. v = cycle;
  136. break;
  137. case GlobalTimeout:
  138. v = CYCLE_TIMEOUT;
  139. break;
  140. }
  141. }
  142. void Simulator::decodeInstructionParameters(Program& program, Task& task, const Instruction& instruction) {
  143. task.a = instruction.a;
  144. task.b = instruction.b;
  145. task.c = instruction.c;
  146. task.var_a = nullptr;
  147. task.var_b = nullptr;
  148. task.var_c = nullptr;
  149. switch(instruction.params) {
  150. case N:
  151. break;
  152. case L:
  153. task.a = instruction.a;
  154. break;
  155. case V:
  156. decode(program, task, task.a, task.var_a, instruction.a);
  157. break;
  158. case LL:
  159. task.a = instruction.a;
  160. task.b = instruction.b;
  161. break;
  162. case LV:
  163. task.a = instruction.a;
  164. decode(program, task, task.b, task.var_b, instruction.b);
  165. break;
  166. case VL:
  167. decode(program, task, task.a, task.var_a, instruction.a);
  168. task.b = instruction.b;
  169. break;
  170. case VV:
  171. decode(program, task, task.a, task.var_a, instruction.a);
  172. decode(program, task, task.b, task.var_b, instruction.b);
  173. break;
  174. case LLL:
  175. task.a = instruction.a;
  176. task.b = instruction.b;
  177. task.c = instruction.c;
  178. break;
  179. case LLV:
  180. task.a = instruction.a;
  181. task.b = instruction.b;
  182. decode(program, task, task.c, task.var_c, instruction.c);
  183. break;
  184. case LVL:
  185. task.a = instruction.a;
  186. decode(program, task, task.b, task.var_b, instruction.b);
  187. task.c = instruction.c;
  188. break;
  189. case LVV:
  190. task.a = instruction.a;
  191. decode(program, task, task.b, task.var_b, instruction.b);
  192. decode(program, task, task.c, task.var_c, instruction.c);
  193. break;
  194. case VLL:
  195. decode(program, task, task.a, task.var_a, instruction.a);
  196. task.b = instruction.b;
  197. task.c = instruction.c;
  198. break;
  199. case VLV:
  200. decode(program, task, task.a, task.var_a, instruction.a);
  201. task.b = instruction.b;
  202. decode(program, task, task.c, task.var_c, instruction.c);
  203. break;
  204. case VVL:
  205. decode(program, task, task.a, task.var_a, instruction.a);
  206. decode(program, task, task.b, task.var_b, instruction.b);
  207. task.c = instruction.c;
  208. break;
  209. case VVV:
  210. decode(program, task, task.a, task.var_a, instruction.a);
  211. decode(program, task, task.b, task.var_b, instruction.b);
  212. decode(program, task, task.c, task.var_c, instruction.c);
  213. break;
  214. }
  215. }
  216. void Simulator::loadProgram(QColor color, size_t x, size_t y) {
  217. shared_ptr<Team> team = make_shared<Team>(color);
  218. teams.push_back(team);
  219. programs.push_back(Program(team, Right, Position{x, y}, 2, 50, 1));
  220. ++team->programCount;
  221. programs.back().banks[0] = make_shared<Bank>(team, vector<Instruction>{
  222. Instruction(BJUMP, LL, 1, 0)
  223. });
  224. programs.back().banks[1] = make_shared<Bank>(team, vector<Instruction>{
  225. Instruction(SCAN, V, 1),
  226. Instruction(CREATE, LLL, 2, 50, 1),
  227. Instruction(TRANS, LL, 1, 1),
  228. Instruction(TRANS, LL, 2, 2),
  229. Instruction(SET, VL, RemoteActive, 1),
  230. Instruction(TURN, L, 0),
  231. Instruction(AJUMP, L, 0)
  232. });
  233. programs.back().active = team->id;
  234. }
  235. Program* Simulator::findProgram(Position position) {
  236. for(auto& program : programs) {
  237. if(program.position.x == position.x && program.position.y == position.y && program.error == NoError) {
  238. return &program;
  239. }
  240. }
  241. return nullptr;
  242. }
  243. void Simulator::removeErroneousPrograms() {
  244. auto it = std::remove_if(programs.begin(), programs.end(), [](const Program& program){ return program.error != NoError; });
  245. for(auto itr = it; itr != programs.end(); ++itr) {
  246. --(itr->team->programCount);
  247. }
  248. programs.erase(it, programs.end());
  249. }
  250. void Simulator::simulate() {
  251. removeErroneousPrograms();
  252. for (auto& program : programs) {
  253. auto& taskIndex = program.taskIndex;
  254. // do nothing if not active
  255. if(!program.active) {
  256. continue;
  257. }
  258. // error if no active task exists
  259. if(find_if(program.tasks.begin(), program.tasks.end(), [](const Task& task){ return !task.paused; }) == program.tasks.end()) {
  260. program.error = Unemployment;
  261. continue;
  262. }
  263. // switch to next unpasued task
  264. do {
  265. taskIndex = (taskIndex + 1) % program.tasks.size();
  266. } while(program.tasks[taskIndex].paused);
  267. // check if we are still executing an instruction
  268. auto& task = program.tasks[taskIndex];
  269. if(task.remainingCycles > 0) {
  270. --task.remainingCycles;
  271. continue;
  272. }
  273. else {
  274. endInstruction(program, task);
  275. beginInstruction(program, task);
  276. }
  277. }
  278. ++cycle;
  279. }
  280. void Simulator::beginInstruction(Program& program, Task& task) {
  281. // handle invalid bank number
  282. if(program.banks.empty() || task.bankIndex >= program.banks.size()) {
  283. program.error = InvalidBankNumber;
  284. return;
  285. }
  286. // handle autoreset to bank 0,0 if instructionIndex is out of banks bound or bank is empty
  287. if(!program.banks[task.bankIndex] || task.instIndex >= program.banks[task.bankIndex]->instructions.size()) {
  288. task.bankIndex = 0;
  289. task.instIndex = 0;
  290. }
  291. // handle data hunger
  292. if(task.bankIndex == 0 && !program.banks[0]) {
  293. program.error = DataHunger;
  294. return;
  295. }
  296. task.execBank = program.banks[task.bankIndex];
  297. auto& instruction = program.banks[task.bankIndex]->instructions[task.instIndex];
  298. // decode instruction parameters
  299. decodeInstructionParameters(program, task, instruction);
  300. // calculate cycle durations and check preconditions
  301. switch(instruction.command) {
  302. case CREATE:
  303. if(program.instructionSet < 2) {
  304. program.error = HigherInstructionSetRequired;
  305. break;
  306. }
  307. if(task.a < 0 || task.a > 2 || task.b < 1 || task.b > 50 || task.c < 0 || task.c > 1) {
  308. program.error = InvalidParameter;
  309. break;
  310. }
  311. task.remainingCycles = 100 + 50 * task.a + 25 * task.b + 120 * task.c;
  312. break;
  313. case MOVE:
  314. if(program.mobile < 1) {
  315. program.error = MobilityRequired;
  316. break;
  317. }
  318. task.remainingCycles = 20;
  319. break;
  320. case DIE:
  321. task.remainingCycles = 1;
  322. break;
  323. case TRANS: {
  324. int ar = task.a - 1;
  325. int br = task.b - 1;
  326. if(program.instructionSet < 1) {
  327. program.error = HigherInstructionSetRequired;
  328. break;
  329. }
  330. if(ar < 0 || ar >= program.banks.size()) {
  331. program.error = InvalidBankNumber;
  332. break;
  333. }
  334. const auto& bank = program.banks[ar];
  335. task.remainingCycles = 14 + (bank ? bank->instructions.size() : 0);
  336. break;
  337. }
  338. case RTRANS: {
  339. int ar = task.a - 1;
  340. int br = task.b - 1;
  341. if(program.instructionSet < 1) {
  342. program.error = HigherInstructionSetRequired;
  343. break;
  344. }
  345. if(ar < 0 || ar >= 50 || br < 0 || br >= program.banks.size()) {
  346. program.error = InvalidBankNumber;
  347. break;
  348. }
  349. auto remotePosition = calcPosition(program.position, task.direction, 1);
  350. auto remoteProgram = findProgram(remotePosition);
  351. task.remainingCycles = 14 + remoteProgram ? (ar < remoteProgram->banks.size() ? (remoteProgram->banks[ar] ? remoteProgram->banks[ar]->instructions.size() : 0): 0): 0;
  352. break;
  353. }
  354. case TURN:
  355. task.remainingCycles = 8;
  356. break;
  357. case JUMP:
  358. task.remainingCycles = 1;
  359. break;
  360. case AJUMP:
  361. task.remainingCycles = 1;
  362. break;
  363. case BJUMP:
  364. task.remainingCycles = 2;
  365. break;
  366. case SCAN:
  367. if(program.instructionSet < 1) {
  368. program.error = HigherInstructionSetRequired;
  369. break;
  370. }
  371. task.remainingCycles = 8;
  372. break;
  373. case FARSCAN:
  374. if(program.instructionSet < 1) {
  375. program.error = HigherInstructionSetRequired;
  376. break;
  377. }
  378. task.remainingCycles = 10 + 3 * task.c;
  379. break;
  380. case SET:
  381. task.remainingCycles = 2;
  382. break;
  383. case ADD:
  384. task.remainingCycles = 2;
  385. break;
  386. case SUB:
  387. task.remainingCycles = 2;
  388. break;
  389. case MUL:
  390. task.remainingCycles = 2;
  391. break;
  392. case DIV:
  393. task.remainingCycles = 2;
  394. break;
  395. case MOD:
  396. task.remainingCycles = 2;
  397. break;
  398. case MIN:
  399. task.remainingCycles = 2;
  400. break;
  401. case MAX:
  402. task.remainingCycles = 2;
  403. break;
  404. case RANDOM:
  405. if(task.b > task.c) {
  406. program.error = InvalidParameter;
  407. break;
  408. }
  409. task.remainingCycles = 1;
  410. break;
  411. case IF:
  412. task.remainingCycles = 2;
  413. break;
  414. case IFN:
  415. task.remainingCycles = 2;
  416. break;
  417. case IFG:
  418. task.remainingCycles = 2;
  419. break;
  420. case IFL:
  421. task.remainingCycles = 2;
  422. break;
  423. case IFGE:
  424. task.remainingCycles = 2;
  425. break;
  426. case IFLE:
  427. task.remainingCycles = 2;
  428. break;
  429. case INIT:
  430. task.remainingCycles = 2;
  431. break;
  432. case BREAK:
  433. task.remainingCycles = 1;
  434. break;
  435. case RESUME:
  436. task.remainingCycles = 1;
  437. break;
  438. case SEIZE:
  439. task.remainingCycles = 1;
  440. break;
  441. case SLEEP:
  442. if(task.a > 2000) {
  443. program.error = InvalidParameter;
  444. break;
  445. }
  446. task.remainingCycles = task.a;
  447. break;
  448. case QUIT:
  449. task.remainingCycles = 1;
  450. break;
  451. }
  452. }
  453. void Simulator::endInstruction(Program& program, Task& task) {
  454. // we are not executing yet
  455. if(!task.execBank || program.error != NoError) {
  456. return;
  457. }
  458. // check if bank is overwritten, skip execution of current command and begin new bank at instruction 0
  459. if(task.execBank != program.banks[task.bankIndex]) {
  460. task.instIndex = 0;
  461. return;
  462. }
  463. // execute command
  464. auto& instruction = task.execBank->instructions[task.instIndex];
  465. switch(instruction.command) {
  466. case CREATE: {
  467. auto remotePosition = calcPosition(program.position, task.direction, 1);
  468. auto remoteProgram = findProgram(remotePosition);
  469. if(!remoteProgram) {
  470. programs.push_back(Program(program.team, task.direction, remotePosition, task.a, task.b, task.c));
  471. ++program.team->programCount;
  472. }
  473. task.instIndex += 1;
  474. break;
  475. }
  476. case MOVE: {
  477. auto remotePosition = calcPosition(program.position, task.direction, 1);
  478. auto remoteProgram = findProgram(remotePosition);
  479. if(!remoteProgram) {
  480. program.position = remotePosition;
  481. }
  482. task.instIndex += 1;
  483. break;
  484. }
  485. case DIE: {
  486. program.error = DieExecuted;
  487. task.instIndex += 1;
  488. break;
  489. }
  490. case TRANS: {
  491. int ar = task.a - 1;
  492. int br = task.b - 1;
  493. auto remotePosition = calcPosition(program.position, task.direction, 1);
  494. auto remoteProgram = findProgram(remotePosition);
  495. if(remoteProgram && br < remoteProgram->banks.size() && ar < program.banks.size()) {
  496. remoteProgram->banks[br] = program.banks[ar];
  497. }
  498. task.instIndex += 1;
  499. break;
  500. }
  501. case RTRANS: {
  502. int ar = task.a - 1;
  503. int br = task.b - 1;
  504. auto remotePosition = calcPosition(program.position, task.direction, 1);
  505. auto remoteProgram = findProgram(remotePosition);
  506. if(remoteProgram && ar < remoteProgram->banks.size() && br < program.banks.size()) {
  507. program.banks[br] = remoteProgram->banks[ar];
  508. }
  509. task.instIndex += 1;
  510. break;
  511. }
  512. case TURN: {
  513. task.direction = static_cast<Direction>(qMax(0, (task.direction + ((task.a >= 0) ? 1 : -1)) % 4));
  514. task.instIndex += 1;
  515. break;
  516. }
  517. case JUMP: {
  518. task.instIndex += task.a;
  519. break;
  520. }
  521. case AJUMP: {
  522. task.instIndex = task.a - 1;
  523. break;
  524. }
  525. case BJUMP: {
  526. task.bankIndex = task.a - 1;
  527. task.instIndex = task.b - 1;
  528. break;
  529. }
  530. case SCAN: {
  531. // Scans a field, result in #a
  532. // #a=0 ...empty.
  533. // #a=1 ...enemy
  534. // #a=2 ...friend
  535. auto remotePosition = calcPosition(program.position, task.direction, 1);
  536. auto remoteProgram = findProgram(remotePosition);
  537. *task.var_a = !remoteProgram ? 0 : remoteProgram->team == program.team ? 2: 1;
  538. task.instIndex += 1;
  539. break;
  540. }
  541. case FARSCAN: {
  542. // Scans up to c fields straight in front of the bot.
  543. // The nearest bot's type is stored in #a:
  544. // #a=0 ...empty.
  545. // #a=1 ...enemy
  546. // #a=2 ...friend
  547. // Its distance is stored in #b.
  548. *task.var_a = 0;
  549. *task.var_b = 0;
  550. for(int i = 0; i < task.c; ++i) {
  551. auto remotePosition = calcPosition(program.position, task.direction, i + 1);
  552. auto remoteProgram = findProgram(remotePosition);
  553. if(remoteProgram) {
  554. *task.var_a = remoteProgram->team == program.team ? 2: 1;
  555. *task.var_b = i;
  556. break;
  557. }
  558. }
  559. task.instIndex += 1;
  560. break;
  561. }
  562. case SET:
  563. *task.var_a = task.b;
  564. task.instIndex += 1;
  565. break;
  566. case ADD:
  567. *task.var_a += task.b;
  568. task.instIndex += 1;
  569. break;
  570. case SUB:
  571. *task.var_a -= task.b;
  572. task.instIndex += 1;
  573. break;
  574. case MUL:
  575. *task.var_a *= task.b;
  576. task.instIndex += 1;
  577. break;
  578. case DIV:
  579. if(task.b == 0) {
  580. program.error = DivisionByZero;
  581. break;
  582. }
  583. *task.var_a /= task.b;
  584. task.instIndex += 1;
  585. break;
  586. case MOD:
  587. if(task.b == 0) {
  588. program.error = DivisionByZero;
  589. break;
  590. }
  591. *task.var_a %= task.b;
  592. task.instIndex += 1;
  593. break;
  594. case MIN:
  595. *task.var_a = qMin(task.a, task.b);
  596. task.instIndex += 1;
  597. break;
  598. case MAX:
  599. *task.var_a = qMax(task.a, task.b);
  600. task.instIndex += 1;
  601. break;
  602. case RANDOM:
  603. *task.var_a = task.b + (rand() % (task.c - task.b + 1));
  604. task.instIndex += 1;
  605. break;
  606. case IF:
  607. task.instIndex += ((task.a == task.b) ? 1 : 2);
  608. break;
  609. case IFN:
  610. task.instIndex += ((task.a != task.b) ? 1 : 2);
  611. break;
  612. case IFG:
  613. task.instIndex += ((task.a > task.b) ? 1 : 2);
  614. break;
  615. case IFL:
  616. task.instIndex += ((task.a < task.b) ? 1 : 2);
  617. break;
  618. case IFGE:
  619. task.instIndex += ((task.a >= task.b) ? 1 : 2);
  620. break;
  621. case IFLE:
  622. task.instIndex += ((task.a <= task.b) ? 1 : 2);
  623. break;
  624. case INIT:
  625. task.instIndex += 1;
  626. break;
  627. case BREAK:
  628. task.instIndex += 1;
  629. break;
  630. case RESUME:
  631. task.instIndex += 1;
  632. break;
  633. case SEIZE:
  634. task.instIndex += 1;
  635. break;
  636. case SLEEP:
  637. task.instIndex += 1;
  638. break;
  639. case QUIT:
  640. task.instIndex += 1;
  641. break;
  642. default:
  643. task.instIndex += 1;
  644. break;
  645. }
  646. }