MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Interpreter.hpp
1 /*
2  Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #ifndef NDB_INTERPRETER_HPP
19 #define NDB_INTERPRETER_HPP
20 
21 #include <ndb_types.h>
22 
23 class Interpreter {
24 public:
25 
26  inline static Uint32 mod4(Uint32 len){
27  return len + ((4 - (len & 3)) & 3);
28  }
29 
30 
49  STATIC_CONST( READ_ATTR_INTO_REG = 1 );
50  STATIC_CONST( WRITE_ATTR_FROM_REG = 2 );
51  STATIC_CONST( LOAD_CONST_NULL = 3 );
52  STATIC_CONST( LOAD_CONST16 = 4 );
53  STATIC_CONST( LOAD_CONST32 = 5 );
54  STATIC_CONST( LOAD_CONST64 = 6 );
55  STATIC_CONST( ADD_REG_REG = 7 );
56  STATIC_CONST( SUB_REG_REG = 8 );
57  STATIC_CONST( BRANCH = 9 );
58  STATIC_CONST( BRANCH_REG_EQ_NULL = 10 );
59  STATIC_CONST( BRANCH_REG_NE_NULL = 11 );
60  STATIC_CONST( BRANCH_EQ_REG_REG = 12 );
61  STATIC_CONST( BRANCH_NE_REG_REG = 13 );
62  STATIC_CONST( BRANCH_LT_REG_REG = 14 );
63  STATIC_CONST( BRANCH_LE_REG_REG = 15 );
64  STATIC_CONST( BRANCH_GT_REG_REG = 16 );
65  STATIC_CONST( BRANCH_GE_REG_REG = 17 );
66  STATIC_CONST( EXIT_OK = 18 );
67  STATIC_CONST( EXIT_REFUSE = 19 );
68  STATIC_CONST( CALL = 20 );
69  STATIC_CONST( RETURN = 21 );
70  STATIC_CONST( EXIT_OK_LAST = 22 );
71  STATIC_CONST( BRANCH_ATTR_OP_ARG = 23 );
72  STATIC_CONST( BRANCH_ATTR_EQ_NULL = 24 );
73  STATIC_CONST( BRANCH_ATTR_NE_NULL = 25 );
74  STATIC_CONST( BRANCH_ATTR_OP_ARG_2 = 26 );
75 
79  static Uint32 Read(Uint32 AttrId, Uint32 Register);
80  static Uint32 Write(Uint32 AttrId, Uint32 Register);
81 
82  static Uint32 LoadNull(Uint32 Register);
83  static Uint32 LoadConst16(Uint32 Register, Uint32 Value);
84  static Uint32 LoadConst32(Uint32 Register); // Value in next word
85  static Uint32 LoadConst64(Uint32 Register); // Value in next 2 words
86  static Uint32 Add(Uint32 DstReg, Uint32 SrcReg1, Uint32 SrcReg2);
87  static Uint32 Sub(Uint32 DstReg, Uint32 SrcReg1, Uint32 SrcReg2);
88  static Uint32 Branch(Uint32 Inst, Uint32 Reg1, Uint32 Reg2);
89  static Uint32 ExitOK();
90 
110  IS_NULL = 0,
111  IS_NOT_NULL = 1
112  };
113 
114  enum BinaryCondition {
115  EQ = 0,
116  NE = 1,
117  LT = 2,
118  LE = 3,
119  GT = 4,
120  GE = 5,
121  LIKE = 6,
122  NOT_LIKE = 7,
123  AND_EQ_MASK = 8,
124  AND_NE_MASK = 9,
125  AND_EQ_ZERO = 10,
126  AND_NE_ZERO = 11
127  };
128  // TODO : Remove other 2 unused parameters.
129  static Uint32 BranchCol(BinaryCondition cond,
130  Uint32 arrayLengthDiff, Uint32 varchar);
131  static Uint32 BranchCol_2(Uint32 AttrId);
132  static Uint32 BranchCol_2(Uint32 AttrId, Uint32 Len);
133 
134  static Uint32 BranchColParameter(BinaryCondition cond);
135  static Uint32 BranchColParameter_2(Uint32 AttrId, Uint32 ParamNo);
136 
137  static Uint32 getBinaryCondition(Uint32 op1);
138  static Uint32 getArrayLengthDiff(Uint32 op1);
139  static Uint32 isVarchar(Uint32 op1);
140  static Uint32 getBranchCol_AttrId(Uint32 op2);
141  static Uint32 getBranchCol_Len(Uint32 op2);
142  static Uint32 getBranchCol_ParamNo(Uint32 op2);
143 
147  static Uint32 getOpCode(Uint32 op);
148  static Uint32 getReg1(Uint32 op);
149  static Uint32 getReg2(Uint32 op);
150  static Uint32 getReg3(Uint32 op);
151  static Uint32 getLabel(Uint32 op);
152 
157  {
158  NONE,
159  LABEL_ADDRESS_REPLACEMENT,
160  SUB_ADDRESS_REPLACEMENT
161  };
162 
163  /* This method is used to determine what sort of
164  * instruction processing is required, and the address
165  * of the next instruction in the stream
166  */
167  static Uint32 *getInstructionPreProcessingInfo(Uint32 *op,
168  InstructionPreProcessing& processing);
169 };
170 
171 inline
172 Uint32
173 Interpreter::Read(Uint32 AttrId, Uint32 Register){
174  return (AttrId << 16) + (Register << 6) + READ_ATTR_INTO_REG;
175 }
176 
177 inline
178 Uint32
179 Interpreter::Write(Uint32 AttrId, Uint32 Register){
180  return (AttrId << 16) + (Register << 6) + WRITE_ATTR_FROM_REG;
181 }
182 
183 inline
184 Uint32
185 Interpreter::LoadNull(Uint32 Register){
186  return (Register << 6) + LOAD_CONST_NULL;
187 }
188 
189 inline
190 Uint32
191 Interpreter::LoadConst16(Uint32 Register, Uint32 Value){
192  return (Value << 16) + (Register << 6) + LOAD_CONST16;
193 }
194 
195 inline
196 Uint32
197 Interpreter::LoadConst32(Uint32 Register){
198  return (Register << 6) + LOAD_CONST32;
199 }
200 
201 inline
202 Uint32
203 Interpreter::LoadConst64(Uint32 Register){
204  return (Register << 6) + LOAD_CONST64;
205 }
206 
207 inline
208 Uint32
209 Interpreter::Add(Uint32 Dcoleg, Uint32 SrcReg1, Uint32 SrcReg2){
210  return (SrcReg1 << 6) + (SrcReg2 << 9) + (Dcoleg << 16) + ADD_REG_REG;
211 }
212 
213 inline
214 Uint32
215 Interpreter::Sub(Uint32 Dcoleg, Uint32 SrcReg1, Uint32 SrcReg2){
216  return (SrcReg1 << 6) + (SrcReg2 << 9) + (Dcoleg << 16) + SUB_REG_REG;
217 }
218 
219 inline
220 Uint32
221 Interpreter::Branch(Uint32 Inst, Uint32 Reg1, Uint32 Reg2){
222  return (Reg1 << 9) + (Reg2 << 6) + Inst;
223 }
224 
225 inline
226 Uint32
227 Interpreter::BranchCol(BinaryCondition cond,
228  Uint32 arrayLengthDiff,
229  Uint32 varchar){
230  //ndbout_c("BranchCol: cond=%d diff=%u varchar=%u",
231  //cond, arrayLengthDiff, varchar);
232  return
233  BRANCH_ATTR_OP_ARG +
234  (arrayLengthDiff << 9) +
235  (varchar << 11) +
236  (cond << 12);
237 }
238 
239 inline
240 Uint32
241 Interpreter::BranchColParameter(BinaryCondition cond)
242 {
243  return BRANCH_ATTR_OP_ARG_2 + (cond << 12);
244 }
245 
246 inline
247 Uint32
248 Interpreter::BranchColParameter_2(Uint32 AttrId, Uint32 ParamNo){
249  return (AttrId << 16) + ParamNo;
250 }
251 
252 inline
253 Uint32
254 Interpreter::BranchCol_2(Uint32 AttrId, Uint32 Len){
255  return (AttrId << 16) + Len;
256 }
257 
258 inline
259 Uint32
260 Interpreter::BranchCol_2(Uint32 AttrId){
261  return (AttrId << 16);
262 }
263 
264 inline
265 Uint32
266 Interpreter::getBinaryCondition(Uint32 op){
267  return (op >> 12) & 0xf;
268 }
269 
270 inline
271 Uint32
272 Interpreter::getArrayLengthDiff(Uint32 op){
273  return (op >> 9) & 0x3;
274 }
275 
276 inline
277 Uint32
278 Interpreter::isVarchar(Uint32 op){
279  return (op >> 11) & 1;
280 }
281 
282 inline
283 Uint32
284 Interpreter::getBranchCol_AttrId(Uint32 op){
285  return (op >> 16) & 0xFFFF;
286 }
287 
288 inline
289 Uint32
290 Interpreter::getBranchCol_Len(Uint32 op){
291  return op & 0xFFFF;
292 }
293 
294 inline
295 Uint32
296 Interpreter::getBranchCol_ParamNo(Uint32 op){
297  return op & 0xFFFF;
298 }
299 
300 inline
301 Uint32
302 Interpreter::ExitOK(){
303  return EXIT_OK;
304 }
305 
306 inline
307 Uint32
309  return op & 0x3f;
310 }
311 
312 inline
313 Uint32
314 Interpreter::getReg1(Uint32 op){
315  return (op >> 6) & 0x7;
316 }
317 
318 inline
319 Uint32
320 Interpreter::getReg2(Uint32 op){
321  return (op >> 9) & 0x7;
322 }
323 
324 inline
325 Uint32
326 Interpreter::getReg3(Uint32 op){
327  return (op >> 16) & 0x7;
328 }
329 
330 inline
331 Uint32
332 Interpreter::getLabel(Uint32 op){
333  return (op >> 16) & 0xffff;
334 }
335 
336 inline
337 Uint32*
338 Interpreter::getInstructionPreProcessingInfo(Uint32 *op,
339  InstructionPreProcessing& processing )
340 {
341  /* Given an instruction, get a pointer to the
342  * next instruction in the stream.
343  * Returns NULL on error.
344  */
345  processing= NONE;
346  Uint32 opCode= getOpCode(*op);
347 
348  switch( opCode )
349  {
350  case READ_ATTR_INTO_REG:
351  case WRITE_ATTR_FROM_REG:
352  case LOAD_CONST_NULL:
353  case LOAD_CONST16:
354  return op + 1;
355  case LOAD_CONST32:
356  return op + 2;
357  case LOAD_CONST64:
358  return op + 3;
359  case ADD_REG_REG:
360  case SUB_REG_REG:
361  return op + 1;
362  case BRANCH:
363  case BRANCH_REG_EQ_NULL:
364  case BRANCH_REG_NE_NULL:
365  case BRANCH_EQ_REG_REG:
366  case BRANCH_NE_REG_REG:
367  case BRANCH_LT_REG_REG:
368  case BRANCH_LE_REG_REG:
369  case BRANCH_GT_REG_REG:
370  case BRANCH_GE_REG_REG:
371  processing= LABEL_ADDRESS_REPLACEMENT;
372  return op + 1;
373  case BRANCH_ATTR_OP_ARG:
374  {
375  /* We need to take the length from the second word of the
376  * branch instruction so we can skip over the inline const
377  * comparison data.
378  */
379  processing= LABEL_ADDRESS_REPLACEMENT;
380  Uint32 byteLength= getBranchCol_Len(*(op+1));
381  Uint32 wordLength= (byteLength + 3) >> 2;
382  return op+2+wordLength;
383  }
384  case BRANCH_ATTR_OP_ARG_2:
385  {
386  /* We need to take the length from the second word of the
387  * branch instruction so we can skip over the inline const
388  * comparison data.
389  */
390  processing= LABEL_ADDRESS_REPLACEMENT;
391  return op+2;
392  }
393  case BRANCH_ATTR_EQ_NULL:
394  case BRANCH_ATTR_NE_NULL:
395  processing= LABEL_ADDRESS_REPLACEMENT;
396  return op+2;
397  case EXIT_OK:
398  case EXIT_OK_LAST:
399  case EXIT_REFUSE:
400  return op+1;
401  case CALL:
402  processing= SUB_ADDRESS_REPLACEMENT;
403  case RETURN:
404  return op+1;
405 
406  default:
407  return NULL;
408  }
409 }
410 
411 #endif