Advertisement
NovaYoshi

JoshVM

Mar 17th, 2014
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 17.47 KB | None | 0 0
  1. // Joshobotic VM
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <stdlib.h>
  7.  
  8. enum ValueTypes {
  9.   VALUE_8POS, VALUE_8NEG, VALUE_16POS, VALUE_16NEG, VALUE_32CONST, VALUE_VARIABLE, VALUE_FUNCTION, VALUE_ORIGINAL,
  10.   VALUE_ADDITION, VALUE_SUBTRACT, VALUE_MULTIPLY, VALUE_DIVIDE, VALUE_MODULO, VALUE_BIT_AND, VALUE_BIT_OR, VALUE_BIT_XOR,
  11.   VALUE_TERNARY, VALUE_MIN, VALUE_MAX, VALUE_NEGATE, VALUE_INDIRECT, VALUE_INDIRECT_INDEX, VALUE_SHIFT_LEFT, VALUE_SHIFT_RIGHT,
  12.   VALUE_BOOL_TO_VAL1, VALUE_BOOL_TO_VAL2, VALUE_ARRAYVALUE, VALUE_ARRAYREFERENCE, VALUE_BIT_NOT, VALUE_INDIRECT_SET,
  13.   VALUE_INCREMENT, VALUE_DECREMENT,
  14.   VALUE_PREDEC_INDIRECT, VALUE_PREINC_INDIRECT, VALUE_POSTDEC_INDIRECT, VALUE_POSTINC_INDIRECT,
  15.   VALUE_POST_ADD, VALUE_POST_SUB, VALUE_LOOP_INDEX,
  16.  
  17.   VALUE_4POS = 0x30, VALUE_4NEG = 0x40, VALUE_FUNCARG = 0x50, VALUE_ARGREF = 0x60,
  18. };
  19. enum BoolTypes {
  20.   BOOL_CMP, BOOL_NOT, BOOL_AND, BOOL_OR, BOOL_XOR, BOOL_NAND, BOOL_NOR, BOOL_NXOR, BOOL_TRUE, BOOL_FALSE, BOOL_RANDOM, BOOL_NONZERO
  21.   BOOL_FUNCTION, BOOL_MEMCMP, BOOL_STRCMP, BOOL_STRCASECMP,
  22.   BOOL_EQUAL, BOOL_NOTEQUAL, BOOL_LESSTHAN, BOOL_LESSEQUAL, BOOL_GREATERTHAN, BOOL_GREATEREQUAL,
  23.   BOOL_AND3, BOOL_AND4, BOOL_AND5, BOOL_OR3, BOOL_OR4, BOOL_OR5
  24. };
  25. enum CompTypes {
  26.   COMP_EQUALTO, COMP_NOTEQUAL, COMP_LESSTHAN, COMP_LESSEQUAL, COMP_GREATERTHAN, COMP_GREATEREQUAL
  27. };
  28. enum OpcodeTypes {
  29.   OPCODE_SET = 0x08, OPCODE_SWAP = 0x0c, OPCODE_MATH = 0x10, OPCODE_RMATH = 0x14,
  30.   OPCODE_GOTO = 0x18, OPCODE_CALL = 0x1b, OPCODE_RETURN = 0x1e,  OPCODE_FRET = 0x20,
  31.   OPCODE_INITLOCAL = 0x23, OPCODE_ACALL = 0x24, OPCODE_ATAIL = 0x26, OPCODE_ARET = 0x28
  32. };
  33. //set, swap, add, sub, goto, call, return, function return, initlocal, argument call, argument tailcall, argument return
  34.  
  35. void JVM_InitVM(JVM_Info *VM) {
  36.   VM->PC = 0;
  37.   VM->ParamStackPointer = 0;
  38.   VM->ReturnStackPointer = 0;
  39.   int i,j;
  40.   for(i=0;i<JVM_PARAM_STACK_LENGTH;i++)
  41.     for(j=0;j<JVM_PARAM_STACK_ITEMS;j++)
  42.       VM->ParamStackData[i][j]=0;
  43. }
  44.  
  45. char JVM_Compare2(char Code, signed long A, signed long B) {
  46.   switch(Code) {
  47.     case COMP_EQUALTO:
  48.       return A==B;
  49.     case COMP_NOTEQUAL:
  50.       return A!=B;
  51.     case COMP_LESSTHAN:
  52.       return A<B;
  53.     case COMP_LESSEQUAL:
  54.       return A<=B;
  55.     case COMP_GREATERTHAN:
  56.       return A>B;
  57.     case COMP_GREATEREQUAL:
  58.       return A>=B;
  59.   }
  60.   return 0;
  61. }
  62. signed long JVM_ReadValue(JVM_Info*, unsigned char*, unsigned char**);
  63. char JVM_ReadBool(JVM_Info *VM, unsigned char *Peek, unsigned char **End) {
  64.   long A, B, C, D, E;
  65.   unsigned char op = *(Peek++);
  66.   switch(op) {
  67.     case BOOL_CMP:
  68.       A = JVM_ReadValue(VM, Peek,   End);
  69.       B = JVM_ReadValue(VM, *End,   End);
  70.       C = JVM_ReadValue(VM, *End,   End);
  71.       return JVM_Compare2(A, B, C);
  72.     case BOOL_NOT:
  73.       return !JVM_ReadBool(VM, Peek,   End);
  74.     case BOOL_AND:
  75.       A = JVM_ReadBool(VM, Peek,   End);
  76.       B = JVM_ReadBool(VM, *End,   End);
  77.       return A&&B;
  78.     case BOOL_OR:
  79.       A = JVM_ReadBool(VM, Peek,   End);
  80.       B = JVM_ReadBool(VM, *End,   End);
  81.       return A||B;
  82.     case BOOL_XOR:
  83.       A = JVM_ReadBool(VM, Peek,   End);
  84.       B = JVM_ReadBool(VM, *End,   End);
  85.       return (A!=0)!=(B!=0);
  86.     case BOOL_NAND:
  87.       A = JVM_ReadBool(VM, Peek,   End);
  88.       B = JVM_ReadBool(VM, *End,   End);
  89.       return !(A&&B);
  90.     case BOOL_NOR:
  91.       A = JVM_ReadBool(VM, Peek,   End);
  92.       B = JVM_ReadBool(VM, *End,   End);
  93.       return !(A||B);
  94.     case BOOL_NXOR:
  95.       A = JVM_ReadBool(VM, Peek,   End);
  96.       B = JVM_ReadBool(VM, *End,   End);
  97.       return (A!=0)==(B!=0);
  98.     case BOOL_TRUE:
  99.       return 1;
  100.     case BOOL_FALSE:
  101.       return 0;
  102.     case BOOL_RANDOM:
  103.       return rand()&1;
  104.     case BOOL_NONZERO:
  105.       A = JVM_ReadValue(VM, Peek,   End);
  106.       return A!=0;
  107.       break;
  108.     case BOOL_EQUAL ... CASE BOOL_GREATEREQUAL:
  109.       A = JVM_ReadValue(VM, Peek,   End);
  110.       B = JVM_ReadValue(VM, *End,   End);
  111.       C = JVM_ReadValue(VM, *End,   End);
  112.       return JVM_Compare2(A, B, code-BOOL_EQUAL);
  113.  
  114.     case BOOL_AND3:
  115.       A = JVM_ReadBool(VM, Peek,   End);
  116.       B = JVM_ReadBool(VM, *End,   End);
  117.       C = JVM_ReadBool(VM, *End,   End);
  118.       return A&&B&&C;
  119.     case BOOL_AND4:
  120.       A = JVM_ReadBool(VM, Peek,   End);
  121.       B = JVM_ReadBool(VM, *End,   End);
  122.       C = JVM_ReadBool(VM, *End,   End);
  123.       D = JVM_ReadBool(VM, *End,   End);
  124.       return A&&B&&C&&D;
  125.     case BOOL_AND5:
  126.       A = JVM_ReadBool(VM, Peek,   End);
  127.       B = JVM_ReadBool(VM, *End,   End);
  128.       C = JVM_ReadBool(VM, *End,   End);
  129.       D = JVM_ReadBool(VM, *End,   End);
  130.       E = JVM_ReadBool(VM, *End,   End);
  131.       return A&&B&&C&&D&&E;
  132.     case BOOL_OR3:
  133.       A = JVM_ReadBool(VM, Peek,   End);
  134.       B = JVM_ReadBool(VM, *End,   End);
  135.       C = JVM_ReadBool(VM, *End,   End);
  136.       return A||B||C;
  137.     case BOOL_OR4:
  138.       A = JVM_ReadBool(VM, Peek,   End);
  139.       B = JVM_ReadBool(VM, *End,   End);
  140.       C = JVM_ReadBool(VM, *End,   End);
  141.       D = JVM_ReadBool(VM, *End,   End);
  142.       return A||B||C||D;
  143.     case BOOL_OR5:
  144.       A = JVM_ReadBool(VM, Peek,   End);
  145.       B = JVM_ReadBool(VM, *End,   End);
  146.       C = JVM_ReadBool(VM, *End,   End);
  147.       D = JVM_ReadBool(VM, *End,   End);
  148.       E = JVM_ReadBool(VM, *End,   End);
  149.       return A||B||C||D||E;
  150.   }
  151.   return 0;
  152. }
  153. signed long JVM_ReadValue(JVM_Info *VM, unsigned char *Peek, unsigned char **End) {
  154.   long A, B;
  155.   char cc;
  156.   unsigned short *ShortPtr;
  157.   long *LongPtr;
  158.   JVM_VarAddrSpace *VarPtr;
  159.  
  160.   switch(*(Peek++)) {
  161.     case VALUE_8POS:
  162.       A = (unsigned char)Peek[0];
  163.       (*End)+=2;
  164.       return A;
  165.     case VALUE_8NEG:
  166.       A = (unsigned char)Peek[0];
  167.       (*End)+=2;
  168.       return -A;
  169.     case VALUE_16POS:
  170.       ShortPtr = (unsigned short*)(Peek);
  171.       (*End)+=3;
  172.       return *ShortPtr;
  173.     case VALUE_16NEG:
  174.       ShortPtr = (unsigned short*)(Peek);
  175.       (*End)+=3;
  176.       return -(*ShortPtr);
  177.     case VALUE_32CONST:
  178.       LongPtr = (signed long*)(Peek);
  179.       (*End)+=5;
  180.       return *LongPtr;
  181.     case VALUE_VARIABLE:
  182.       VarPtr = (JVM_VarAddrSpace*)(Peek);
  183.       (*End)+=1+sizeof(JVM_VarAddrSpace);
  184.       return JVM_ReadMemory(VM, *VarPtr);;
  185.     case VALUE_FUNCTION:
  186.       // implement later
  187.       break;
  188.     case VALUE_ORIGINAL:
  189.       return VM->OriginalValue[VM->OriginalValuePointer];
  190.     case VALUE_ADDITION:
  191.       A = JVM_ReadValue(VM, Peek, &Peek);
  192.       B = JVM_ReadValue(VM, Peek,   End);
  193.       return A+B;
  194.     case VALUE_SUBTRACT:
  195.       A = JVM_ReadValue(VM, Peek, &Peek);
  196.       B = JVM_ReadValue(VM, Peek,   End);
  197.       return A-B;
  198.     case VALUE_MULTIPLY:
  199.       A = JVM_ReadValue(VM, Peek, &Peek);
  200.       B = JVM_ReadValue(VM, Peek,   End);
  201.       return A*B;
  202.     case VALUE_DIVIDE:
  203.       A = JVM_ReadValue(VM, Peek, &Peek);
  204.       B = JVM_ReadValue(VM, Peek,   End);
  205.       if(!B) return 0;
  206.       return A/B;
  207.     case VALUE_MODULO:
  208.       A = JVM_ReadValue(VM, Peek, &Peek);
  209.       B = JVM_ReadValue(VM, Peek,   End);
  210.       if(!B) return 0;
  211.       return A%B;
  212.     case VALUE_BIT_AND:
  213.       A = JVM_ReadValue(VM, Peek, &Peek);
  214.       B = JVM_ReadValue(VM, Peek,   End);
  215.       return A&B;
  216.     case VALUE_BIT_OR:
  217.       A = JVM_ReadValue(VM, Peek, &Peek);
  218.       B = JVM_ReadValue(VM, Peek,   End);
  219.       return A|B;
  220.     case VALUE_BIT_XOR:
  221.       A = JVM_ReadValue(VM, Peek, &Peek);
  222.       B = JVM_ReadValue(VM, Peek,   End);
  223.       return A^B;
  224.     case VALUE_TERNARY:
  225.       cc = JVM_ReadBool(VM, Peek, &Peek);
  226.       A = JVM_ReadValue(VM, Peek, &Peek);
  227.       B = JVM_ReadValue(VM, Peek,   End);
  228.       return cc?A:B;
  229.     case VALUE_MIN:
  230.       A = JVM_ReadValue(VM, Peek, &Peek);
  231.       B = JVM_ReadValue(VM, Peek,   End);
  232.       if(A<B) return A;
  233.       return B;
  234.     case VALUE_MAX:
  235.       A = JVM_ReadValue(VM, Peek, &Peek);
  236.       B = JVM_ReadValue(VM, Peek,   End);
  237.       if(A>B) return A;
  238.       return B;
  239.     case VALUE_NEGATE:
  240.       A = JVM_ReadValue(VM, Peek, End);
  241.       return -B;
  242.     case VALUE_INDIRECT:
  243.       A = JVM_ReadValue(VM, Peek, End);
  244.       return JVM_ReadMemory(VM, A);
  245.     case VALUE_INDIRECT_INDEX:
  246.       A = JVM_ReadValue(VM, Peek, &Peek);
  247.       B = JVM_ReadValue(VM, Peek,   End);
  248.       return JVM_ReadMemory(VM, A+B);
  249.     case VALUE_SHIFT_LEFT:
  250.       A = JVM_ReadValue(VM, Peek, &Peek);
  251.       B = JVM_ReadValue(VM, Peek,   End);
  252.       return A<<B;
  253.     case VALUE_SHIFT_RIGHT:
  254.       A = JVM_ReadValue(VM, Peek, &Peek);
  255.       B = JVM_ReadValue(VM, Peek,   End);
  256.       return A>>B;
  257.     case VALUE_BOOL_TO_VAL1:
  258.       A = JVM_ReadBool(VM, Peek,   End);
  259.       return A;
  260.     case VALUE_BOOL_TO_VAL2:
  261.       A = JVM_ReadBool(VM, Peek,   End);
  262.       return -A;
  263.     case VALUE_ARRAYVALUE:
  264.       ShortPtr = (unsigned short*)(Peek);
  265.       Peek+=2;
  266.       A = JVM_ReadValue(VM, Peek,  End);
  267.       return JVM_ReadMemory(VM, A+B);
  268.     case VALUE_ARRAYREFERENCE:
  269.       ShortPtr = (unsigned short*)(Peek);
  270.       Peek+=2;
  271.       A = JVM_ReadValue(VM, Peek,  End);
  272.       return A+B;
  273.     case VALUE_BIT_NOT:
  274.       A = JVM_ReadValue(VM, Peek,  End);
  275.       return ~A;
  276.     case VALUE_INDIRECT_SET:
  277.       A = JVM_ReadValue(VM, Peek, &Peek);
  278.       B = JVM_ReadValue(VM, Peek,   End);
  279.       JVM_WriteMemory(VM, A, B);
  280.       return B;
  281.     case VALUE_INCREMENT:
  282.       A = JVM_ReadValue(VM, Peek,   End);
  283.       return A+1;
  284.     case VALUE_DECREMENT:
  285.       A = JVM_ReadValue(VM, Peek,   End);
  286.       return A-1;
  287.  
  288.     case VALUE_PREDEC_INDIRECT:
  289.       A = JVM_ReadValue(VM, Peek,   End);
  290.       B = JVM_ReadMemory(VM, A)-1;
  291.       JVM_WriteMemory(VM, A, B);
  292.       return B;
  293.     case VALUE_PREINC_INDIRECT:
  294.       A = JVM_ReadValue(VM, Peek,   End);
  295.       B = JVM_ReadMemory(VM, A)+1;
  296.       JVM_WriteMemory(VM, A, B);
  297.       return B;
  298.  
  299.     case VALUE_POSTDEC_INDIRECT:
  300.       A = JVM_ReadValue(VM, Peek,   End);
  301.       B = JVM_ReadMemory(VM, A);
  302.       JVM_WriteMemory(VM, A, B-1);
  303.       return B;
  304.     case VALUE_POSTINC_INDIRECT:
  305.       A = JVM_ReadValue(VM, Peek,   End);
  306.       B = JVM_ReadMemory(VM, A);
  307.       JVM_WriteMemory(VM, A, B+1);
  308.       return B;
  309.  
  310.     case VALUE_POST_ADD: // todo
  311.       A = JVM_ReadValue(VM, Peek,   End);
  312.       B = JVM_ReadMemory(VM, A);
  313.       JVM_WriteMemory(VM, A, B+1);
  314.       return 0;
  315.     case VALUE_POST_SUB:
  316.       A = JVM_ReadValue(VM, Peek,   End);
  317.       B = JVM_ReadMemory(VM, A);
  318.       JVM_WriteMemory(VM, A, B+1);
  319.       return 0;
  320.     case VALUE_LOOP_INDEX:
  321.       return VM->RMathIndex[VM->RMathIndexPointer];
  322.  
  323.     case VALUE_4POS ... VALUE_4POS+15:
  324.       (*End)++;
  325.       return Peek[-1]-VALUE_4POS;
  326.     case VALUE_4NEG ... VALUE_4NEG+15:
  327.       (*End)++;
  328.       return -(Peek[-1]-VALUE_4NEG);
  329.     case VALUE_FUNCARG ... VALUE_FUNCARG+15:
  330.       (*End)++;
  331.       return JVM_ReadMemory(VM, Peek[-1]-VALUE_FUNCARG);
  332.     case VALUE_ARGREF ... VALUE_ARGREF+15:
  333.       (*End)++;
  334.       return 0x2000 + VM->ParamStackPointer + (Peek[-1]-VALUE_ARGREF);
  335.   }
  336.   return 0;
  337. }
  338. //  OPCODE_SET = 0x08, OPCODE_SWAP = 0x0c, OPCODE_MATH = 0x10, OPCODE_RMATH = 0x14,
  339. //  OPCODE_GOTO = 0x18, OPCODE_CALL = 0x1b, OPCODE_RETURN = 0x1e,  OPCODE_FRET = 0x20,
  340. //  OPCODE_ACALL = 0x24, OPCODE_ATAIL = 0x26, OPCODE_ARET = 0x28
  341.  
  342. void inline JVM_SwapInt(signed long *A, signed long *B) {
  343.   signed long T;
  344.   T=*B;
  345.   *B=*A;
  346.   *A=T;
  347. }
  348. #define JVM_PARAM_START 2
  349. void JVM_ReadArgsIntoLocals(JVM_Info *VM, unsigned char *ParPtr, unsigned char **NewParPtr) {
  350.   unsigned char ParamByte = *(ParPtr++);
  351.   unsigned char ParamByteLo = ParamByte & 15;
  352.   unsigned char ParamByteHi = (ParamByte>>4)&15;
  353.   int i;
  354.   signed long Val;
  355.   for(i=0;i<=ParamByteLo;i++) {
  356.     Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  357.     JVM_WriteMemory(VM, (i+ParamByteHi)&15, Val);
  358.   }
  359.   *NewParPtr = ParPtr;
  360. }
  361. int JVM_ExecuteOpcode(JVM_Info *VM) {
  362.   unsigned char Len = VM->Program[VM->PC];
  363.   unsigned char Op = VM->Program[VM->PC+1];
  364.   unsigned char Mod;
  365.   unsigned char Condition=0;
  366.   unsigned char *ParPtr = VM->Program + VM->PC + JVM_PARAM_START;
  367.   signed long Val, Dst, Alt;
  368.   signed long Tmp1, Tmp2;
  369.   unsigned char *OldPtr;
  370.   VM->PC += Len+1;
  371.   switch(Op) {
  372.     case OPCODE_SET ... OPCODE_SWAP-1:
  373.       Mod = Op - OPCODE_SET;
  374.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  375.       if(Mod==1 && !Condition) break;
  376.       Dst = JVM_ReadValue(VM, ParPtr, &ParPtr);
  377.       Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  378.       if(Mod>1) Alt = JVM_ReadValue(VM, ParPtr, &ParPtr);
  379.       if(Mod==2 && Condition) JVM_SwapInt(&Val, &Alt);
  380.       if(Mod==3 && Condition) JVM_SwapInt(&Dst, &Alt);
  381.       JVM_WriteMemory(VM, Dst, Val);
  382.       break;
  383.     case OPCODE_SWAP ... OPCODE_MATH-1:
  384.       Mod = Op - OPCODE_SWAP;
  385.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  386.       if(Mod==1 && !Condition) break;
  387.       Dst = JVM_ReadValue(VM, ParPtr, &ParPtr);
  388.       Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  389.       if(Mod>1) Alt = JVM_ReadValue(VM, ParPtr, &ParPtr);
  390.       if(Mod==2 && Condition) JVM_SwapInt(&Val, &Alt);
  391.       if(Mod==3 && Condition) JVM_SwapInt(&Dst, &Alt);
  392.       Tmp1 = JVM_ReadMemory(VM, Dst);
  393.       Tmp2 = JVM_ReadMemory(VM, Val);
  394.       JVM_WriteMemory(VM, Dst, Tmp2);
  395.       JVM_WriteMemory(VM, Val, Tmp1);
  396.       break;
  397.     case OPCODE_MATH ... OPCODE_RMATH-1:
  398.       Mod = Op - OPCODE_MATH;
  399.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  400.       if(Mod==1 && !Condition) break;
  401.       Dst = JVM_ReadValue(VM, ParPtr, &ParPtr);
  402.       if(Mod>1) Alt = JVM_ReadValue(VM, ParPtr, &ParPtr);
  403.       if(Mod==2 && Condition) JVM_SwapInt(&Val, &Alt);
  404.       if(Mod==3 && Condition) JVM_SwapInt(&Dst, &Alt);
  405.       VM->OriginalValuePointer++;
  406.       VM->OriginalValue[VM->OriginalValuePointer] = JVM_ReadMemory(VM, Dst);
  407.       Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  408.       VM->OriginalValuePointer--;
  409.       JVM_WriteMemory(VM, Dst, Val);
  410.       break;
  411.     case OPCODE_RMATH ... OPCODE_GOTO-1:
  412.       Mod = Op - OPCODE_RMATH;
  413.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  414.       if(Mod==1 && !Condition) break;
  415.       OldPtr = ParPtr;
  416.       Tmp1 = JVM_ReadValue(VM, ParPtr, &ParPtr);
  417.       for(Tmp2=0;Tmp2<Tmp1;Tmp2++) {
  418.         VM->RMathIndexPointer++;
  419.         VM->RMathIndex[VM->OriginalValuePointer] = Tmp2;
  420.         Dst = JVM_ReadValue(VM, ParPtr, &ParPtr);
  421.         VM->OriginalValuePointer++;
  422.         VM->OriginalValue[VM->OriginalValuePointer] = JVM_ReadMemory(VM, Dst);
  423.         Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  424.         VM->OriginalValuePointer--;
  425.         JVM_WriteMemory(VM, Dst, Val);
  426.         VM->RMathIndexPointer--;
  427.       }
  428.       break;
  429.     case OPCODE_GOTO ... OPCODE_CALL-1:
  430.       Mod = Op - OPCODE_GOTO;
  431.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  432.       if(Mod==1 && !Condition) break;
  433.       Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  434.       if(Mod>1) Alt = JVM_ReadValue(VM, ParPtr, &ParPtr);
  435.       if(Mod==2 && Condition) JVM_SwapInt(&Val, &Alt);
  436.       VM->PC = Val;
  437.       break;
  438.     case OPCODE_CALL ... OPCODE_RETURN-1:
  439.       Mod = Op - OPCODE_CALL;
  440.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  441.       if(Mod==1 && !Condition) break;
  442.       Val = JVM_ReadValue(VM, ParPtr, &ParPtr);
  443.       if(Mod>1) Alt = JVM_ReadValue(VM, ParPtr, &ParPtr);
  444.       if(Mod==2 && Condition) JVM_SwapInt(&Val, &Alt);
  445.       VM->ReturnStack[VM->ReturnStackPointer++] = VM->PC;
  446.       VM->PC = Val;
  447.       break;
  448.     case OPCODE_RETURN ... OPCODE_FRET-1:
  449.       Mod = Op - OPCODE_RETURN;
  450.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  451.       if(Mod==1 && !Condition) break;
  452.       VM->PC = VM->ReturnStack[--VM->ReturnStackPointer];
  453.       break;
  454.     case OPCODE_FRET ... OPCODE_INITLOCAL-1:
  455.       Mod = Op - OPCODE_FRET;
  456.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  457.       if(Mod==1 && !Condition) break;
  458.       VM->PC = VM->ReturnStack[--VM->ReturnStackPointer];
  459.       VM->ReturnValue = JVM_ReadValue(VM, ParPtr, &ParPtr);
  460.       VM->ParamStackPointer--;
  461.       break;
  462.     case OPCODE_INITLOCAL:
  463.       JVM_ReadArgsIntoLocals(VM, ParPtr, &ParPtr);
  464.       break;
  465.     case OPCODE_ACALL ... OPCODE_ATAIL-1:
  466.       Mod = Op - OPCODE_ACALL;
  467.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  468.       if(Mod==1 && !Condition) break;
  469.       VM->ReturnStack[VM->ReturnStackPointer++] = VM->PC;
  470.       VM->PC = JVM_ReadValue(VM, ParPtr, &ParPtr);
  471.       VM->ParamStackPointer++;
  472.       JVM_ReadArgsIntoLocals(VM, ParPtr, &ParPtr);
  473.       break;
  474.     case OPCODE_ATAIL ... OPCODE_ARET-1:
  475.       Mod = Op - OPCODE_ATAIL;
  476.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  477.       if(Mod==1 && !Condition) break;
  478.       VM->PC = JVM_ReadValue(VM, ParPtr, &ParPtr);
  479.       VM->ParamStackPointer++;
  480.       JVM_ReadArgsIntoLocals(VM, ParPtr, &ParPtr);
  481.       break;
  482.     case OPCODE_ARET ... OPCODE_ARET+1:
  483.       Mod = Op - OPCODE_RETURN;
  484.       if(Mod!=0) Condition = JVM_ReadBool(VM, ParPtr, &ParPtr);
  485.       if(Mod==1 && !Condition) break;
  486.       VM->PC = VM->ReturnStack[--VM->ReturnStackPointer];
  487.       VM->ParamStackPointer--;
  488.       return 0;
  489.   }
  490.   return 1;
  491. }
  492. int JVM_ExecuteUntilReturn(JVM_Info *VM, int NewPC) {
  493.   int OldSP = VM->ReturnStackPointer;
  494.   VM->ReturnStack[VM->ReturnStackPointer++] = VM->PC;
  495.   VM->PC = NewPC;
  496.   while (JVM_ExecuteOpcode(VM)) {
  497.     printf("%6i %6i %6i %6i %4i %2i %2i\n", (int)VM->ParamStackData[VM->ParamStackPointer][0], (int)VM->ParamStackData[VM->ParamStackPointer][1], (int)VM->ParamStackData[VM->ParamStackPointer][2], (int)VM->ParamStackData[VM->ParamStackPointer][3], VM->PC, VM->ReturnStackPointer, VM->ParamStackPointer);
  498.     if(VM->PC > 100) break;
  499.     if(VM->ReturnStackPointer == OldSP) break;
  500.   }
  501.   return VM->ReturnValue;
  502. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement