• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*=============================================================================
2     Copyright (c) 2001-2011 Joel de Guzman
3 
4     Distributed under the Boost Software License, Version 1.0. (See accompanying
5     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 =============================================================================*/
7 #include "config.hpp"
8 #include "vm.hpp"
9 
10 #if defined(_MSC_VER)
11 # pragma warning(disable: 4800) // forcing value to bool 'true' or 'false'
12                                 // (performance warning)
13 #endif
14 
15 namespace client
16 {
execute(std::vector<int> const & code,std::vector<int>::const_iterator pc,std::vector<int>::iterator frame_ptr)17     int vmachine::execute(
18         std::vector<int> const& code
19       , std::vector<int>::const_iterator pc
20       , std::vector<int>::iterator frame_ptr
21     )
22     {
23         std::vector<int>::iterator stack_ptr = frame_ptr;
24 
25         while (true)
26         {
27             switch (*pc++)
28             {
29                 case op_neg:
30                     stack_ptr[-1] = -stack_ptr[-1];
31                     break;
32 
33                 case op_not:
34                     stack_ptr[-1] = !bool(stack_ptr[-1]);
35                     break;
36 
37                 case op_add:
38                     --stack_ptr;
39                     stack_ptr[-1] += stack_ptr[0];
40                     break;
41 
42                 case op_sub:
43                     --stack_ptr;
44                     stack_ptr[-1] -= stack_ptr[0];
45                     break;
46 
47                 case op_mul:
48                     --stack_ptr;
49                     stack_ptr[-1] *= stack_ptr[0];
50                     break;
51 
52                 case op_div:
53                     --stack_ptr;
54                     stack_ptr[-1] /= stack_ptr[0];
55                     break;
56 
57                 case op_eq:
58                     --stack_ptr;
59                     stack_ptr[-1] = bool(stack_ptr[-1] == stack_ptr[0]);
60                     break;
61 
62                 case op_neq:
63                     --stack_ptr;
64                     stack_ptr[-1] = bool(stack_ptr[-1] != stack_ptr[0]);
65                     break;
66 
67                 case op_lt:
68                     --stack_ptr;
69                     stack_ptr[-1] = bool(stack_ptr[-1] < stack_ptr[0]);
70                     break;
71 
72                 case op_lte:
73                     --stack_ptr;
74                     stack_ptr[-1] = bool(stack_ptr[-1] <= stack_ptr[0]);
75                     break;
76 
77                 case op_gt:
78                     --stack_ptr;
79                     stack_ptr[-1] = bool(stack_ptr[-1] > stack_ptr[0]);
80                     break;
81 
82                 case op_gte:
83                     --stack_ptr;
84                     stack_ptr[-1] = bool(stack_ptr[-1] >= stack_ptr[0]);
85                     break;
86 
87                 case op_and:
88                     --stack_ptr;
89                     stack_ptr[-1] = bool(stack_ptr[-1]) && bool(stack_ptr[0]);
90                     break;
91 
92                 case op_or:
93                     --stack_ptr;
94                     stack_ptr[-1] = bool(stack_ptr[-1]) || bool(stack_ptr[0]);
95                     break;
96 
97                 case op_load:
98                     *stack_ptr++ = frame_ptr[*pc++];
99                     break;
100 
101                 case op_store:
102                     --stack_ptr;
103                     frame_ptr[*pc++] = stack_ptr[0];
104                     break;
105 
106                 case op_int:
107                     *stack_ptr++ = *pc++;
108                     break;
109 
110                 case op_true:
111                     *stack_ptr++ = true;
112                     break;
113 
114                 case op_false:
115                     *stack_ptr++ = false;
116                     break;
117 
118                 case op_jump:
119                     pc += *pc;
120                     break;
121 
122                 case op_jump_if:
123                     if (!bool(stack_ptr[-1]))
124                         pc += *pc;
125                     else
126                         ++pc;
127                     --stack_ptr;
128                     break;
129 
130                 case op_stk_adj:
131                     stack_ptr += *pc++;
132                     break;
133 
134                 case op_call:
135                     {
136                         int nargs = *pc++;
137                         int jump = *pc++;
138 
139                         // a function call is a recursive call to execute
140                         int r = execute(
141                             code
142                           , code.begin() + jump
143                           , stack_ptr - nargs
144                         );
145 
146                         // cleanup after return from function
147                         stack_ptr[-nargs] = r;      //  get return value
148                         stack_ptr -= (nargs - 1);   //  the stack will now contain
149                                                     //  the return value
150                     }
151                     break;
152 
153                 case op_return:
154                     return stack_ptr[-1];
155             }
156         }
157     }
158 }
159 
160 
161