Wolframe, 0.0.3

instructionSet.hpp
Go to the documentation of this file.
1 /************************************************************************
2 
3  Copyright (C) 2011 - 2014 Project Wolframe.
4  All rights reserved.
5 
6  This file is part of Project Wolframe.
7 
8  Commercial Usage
9  Licensees holding valid Project Wolframe Commercial licenses may
10  use this file in accordance with the Project Wolframe
11  Commercial License Agreement provided with the Software or,
12  alternatively, in accordance with the terms contained
13  in a written agreement between the licensee and Project Wolframe.
14 
15  GNU General Public License Usage
16  Alternatively, you can redistribute this file and/or modify it
17  under the terms of the GNU General Public License as published by
18  the Free Software Foundation, either version 3 of the License, or
19  (at your option) any later version.
20 
21  Wolframe is distributed in the hope that it will be useful,
22  but WITHOUT ANY WARRANTY; without even the implied warranty of
23  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24  GNU General Public License for more details.
25 
26  You should have received a copy of the GNU General Public License
27  along with Wolframe. If not, see <http://www.gnu.org/licenses/>.
28 
29  If you have questions regarding the use of this file, please contact
30  Project Wolframe.
31 
32 ************************************************************************/
35 #ifndef _DATABASE_VIRTUAL_MACHINE_INSTRUCTION_SET_HPP_INCLUDED
36 #define _DATABASE_VIRTUAL_MACHINE_INSTRUCTION_SET_HPP_INCLUDED
37 #include <stdexcept>
38 #include <vector>
39 #include <string>
40 #include <sstream>
41 #include <iostream>
42 #include <boost/cstdint.hpp>
43 
44 namespace _Wolframe {
45 namespace db {
46 namespace vm {
47 
51 {
52 public:
55  enum OpCode
56  {
57  // Control Flow Instructions:
58  Op_EXIT, //< exit (abort)
59  Op_RETURN, //< return from subroutine or termination of transaction
60  Op_GOTO, //< goto absolute address
61 
62  // Output Instructions:
63  Op_OUTPUT_CONST, //< print a value to output: constant
64  Op_OUTPUT_PATH, //< print a value to output: unique input path selection
65  Op_OUTPUT_LOOPCNT, //< print a value to output: FOREACH loop counter (first element is 0)
66  Op_OUTPUT_SEL_IDX, //< print a value to output: element in selected set (unique, one element set) adressed by column index
67  Op_OUTPUT_SEL_NAM, //< print a value to output: element in selected set (unique, one element set) adressed by column name
68  Op_OUTPUT_ITR_IDX, //< print a value to output: element in tuple set iterated adressed by column index
69  Op_OUTPUT_ITR_NAM, //< print a value to output: element in tuple set iterated adressed by column name
70  Op_OUTPUT_ITR_COLUMN, //< print the whole column: for each element print OPEN [column name], result value and CLOSE
71  Op_OUTPUT_OPEN_ARRAY, //< print an open tag of an array start to output (index in tagnametab)
72  Op_OUTPUT_OPEN_ELEM, //< print an open tag of an array element to output (index in tagnametab)
73  Op_OUTPUT_OPEN, //< print an open tag of a single element to output (index in tagnametab)
74  Op_OUTPUT_CLOSE_ARRAY, //< print a close tag of an array start to output (no argument)
75  Op_OUTPUT_CLOSE_ELEM, //< print a close tag of an array element to output (no argument)
76  Op_OUTPUT_CLOSE, //< print a close tag of a single element to output (no argument)
77  Op_OUTPUT_ADD_SINK, //< open a new output sink (e.g. for audit function inputs)
78 
79  // Assignment Instructions:
80  Op_KEEP_RESULT, //< keep result
81  Op_SELECT_PARAMETER, //< set value set selected as the parameter list of the subroutine executed
82  Op_SELECT_LAST_RESULT, //< set value set selected as the last result
83  Op_SELECT_KEPT_RESULT, //< set value set selected as a result named with KEEP
84 
85  // Iterator Instructions:
86  Op_OPEN_ITER_LAST_RESULT, //< open a value iterator (set cond flag on !empty): last result
87  Op_OPEN_ITER_KEPT_RESULT, //< open a value iterator (set cond flag on !empty): index is referecing a kept result index
88  Op_OPEN_ITER_PATH, //< open a value iterator (set cond flag on !empty): index is referecing a path
89  Op_OPEN_ITER_TUPLESET, //< open a value iterator (set cond flag on !empty): index is referecing a tuple set
90  Op_NEXT, //< fetch the next value in iteration
91 
92  // Subroutine Call Instructions:
93  Op_SUB_FRAME_OPEN, //< start prepare a subroutine call or an own execution scope
94  Op_SUB_ARG_CONST, //< push argument for subroutine call: constant value
95  Op_SUB_ARG_PATH, //< push argument for subroutine call: path selection value
96  Op_SUB_ARG_LOOPCNT, //< push argument for subroutine call: FOREACH loop counter (first element is 0)
97  Op_SUB_ARG_SEL_IDX, //< push argument for subroutine call: element in selected set (unique, one element set) adressed by column index
98  Op_SUB_ARG_SEL_NAM, //< push argument for subroutine call: element in selected set (unique, one element set) adressed by column name
99  Op_SUB_ARG_ITR_IDX, //< push argument for subroutine call: element in tuple set iterated adressed by column index
100  Op_SUB_ARG_ITR_NAM, //< push argument for subroutine call: element in tuple set iterated adressed by column name
101  Op_SUB_FRAME_CLOSE, //< push state with parameters on stack for subroutine call. For the jump to the subroutine GOTO is used.
102 
103  // Scoping Instructions:
104  Op_SCOPE_OPEN, //< create a new scope context without calling a subroutine (inherits data from parent scope)
105  Op_SCOPE_CLOSE, //< restore the previous scope context
106 
107  // Database Instructions:
108  Op_DBSTM_START, //< open a statement to execute
109  Op_DBSTM_BIND_CONST, //< bind a statement parameter: constant value
110  Op_DBSTM_BIND_PATH, //< bind a statement parameter: path selection value
111  Op_DBSTM_BIND_LOOPCNT, //< bind a statement parameter: FOREACH loop counter (first element is 0)
112  Op_DBSTM_BIND_SEL_IDX, //< bind a statement parameter
113  Op_DBSTM_BIND_SEL_NAM, //< bind a statement parameter
114  Op_DBSTM_BIND_ITR_IDX, //< bind a statement parameter
115  Op_DBSTM_BIND_ITR_NAM, //< bind a statement parameter
116  Op_DBSTM_HINT, //< define a list of hints for open statement
117  Op_DBSTM_EXEC, //< execute open statement
118 
119  // Collect Results and Constraints:
123 
124  // Others:
125  Op_NOP //< no operation
126  };
127  static const char* opCodeName( OpCode i)
128  {
129  static const char* ar[] = {
130  "EXIT",
131  "RETURN",
132  "GOTO",
133 
134  "OUTPUT_CONST",
135  "OUTPUT_PATH",
136  "OUTPUT_LOOPCNT",
137  "OUTPUT_SEL_IDX",
138  "OUTPUT_SEL_NAM",
139  "OUTPUT_ITR_IDX",
140  "OUTPUT_ITR_NAM",
141  "OUTPUT_ITR_COLUMN",
142  "OUTPUT_OPEN_ARRAY",
143  "OUTPUT_OPEN_ELEM",
144  "OUTPUT_OPEN",
145  "OUTPUT_CLOSE_ARRAY",
146  "OUTPUT_CLOSE_ELEM",
147  "OUTPUT_CLOSE",
148  "OUTPUT_ADD_SINK",
149 
150  "KEEP_RESULT",
151  "SELECT_PARAMETER",
152  "SELECT_LAST_RESULT",
153  "SELECT_KEPT_RESULT",
154 
155  "OPEN_ITER_LAST_RESULT",
156  "OPEN_ITER_KEPT_RESULT",
157  "OPEN_ITER_PATH",
158  "OPEN_ITER_TUPLESET",
159  "NEXT",
160 
161  "SUB_FRAME_OPEN",
162  "SUB_ARG_CONST",
163  "SUB_ARG_PATH",
164  "SUB_ARG_LOOPCNT",
165  "SUB_ARG_SEL_IDX",
166  "SUB_ARG_SEL_NAM",
167  "SUB_ARG_ITR_IDX",
168  "SUB_ARG_ITR_NAM",
169  "SUB_FRAME_CLOSE",
170 
171  "SCOPE_OPEN",
172  "SCOPE_CLOSE",
173 
174  "DBSTM_START",
175  "DBSTM_BIND_CONST",
176  "DBSTM_BIND_PATH",
177  "DBSTM_BIND_LOOPCNT",
178  "DBSTM_BIND_SEL_IDX",
179  "DBSTM_BIND_SEL_NAM",
180  "DBSTM_BIND_ITR_IDX",
181  "DBSTM_BIND_ITR_NAM",
182  "DBSTM_HINT",
183  "DBSTM_EXEC",
184 
185  "RESULT_SET_INIT",
186  "RESULT_CONSTRAINT_UNIQUE",
187  "RESULT_CONSTRAINT_NONEMPTY",
188 
189  "NOP"
190  };
191  return ar[i];
192  }
193 
197  {
198  At_None, //< no argument
199  At_Address, //< index in ProgramCode
200  At_Path, //< index in Program::pathset
201  At_Constant, //< index in Program::constants
202  At_ColumnName, //< index in Program::colnametab
203  At_TagName, //< index in Program::tagnametab
204  At_ResultName, //< index in Program::resultnametab
205  At_Statement, //< index in Program::statements
206  At_Hint, //< index in Program::hinttab
207  At_SubroutineSignature, //< index in Program::signatures
208  At_TupleSet, //< index of tuple set
209  At_SelectedColumnIdx, //< Index of Column in selected set
210  At_IteratorColumnIdx //< Index of Column in tuple set iterator element
211  };
212 
214  static const char* argumentTypeName( ArgumentType i)
215  {
216  static const char* ar[] =
217  {
218  "",
219  "Address",
220  "Path",
221  "Constant",
222  "ColumnName",
223  "TagName",
224  "ResultName",
225  "Statement",
226  "SubroutineSignature",
227  "TupleSet",
228  "SelectedColumnIdx",
229  "IteratorColumnIdx"
230  };
231  return ar[i];
232  }
233 
236  {
237  static ArgumentType ar[] =
238  {
239  /*Op_EXIT*/ At_None,
240  /*Op_RETURN*/ At_None,
241  /*Op_GOTO*/ At_Address,
242 
243  /*Op_OUTPUT_CONST*/ At_Constant,
244  /*Op_OUTPUT_PATH*/ At_Path,
245  /*Op_OUTPUT_LOOPCNT*/ At_None,
246  /*Op_OUTPUT_SEL_IDX*/ At_SelectedColumnIdx,
247  /*Op_OUTPUT_SEL_NAM*/ At_ColumnName,
248  /*Op_OUTPUT_ITR_IDX*/ At_IteratorColumnIdx,
249  /*Op_OUTPUT_ITR_NAM*/ At_ColumnName,
250  /*Op_OUTPUT_ITR_COLUMN*/ At_None,
251  /*Op_OUTPUT_OPEN_ARRAY*/ At_TagName,
252  /*Op_OUTPUT_OPEN_ELEM*/ At_None,
253  /*Op_OUTPUT_OPEN*/ At_TagName,
254  /*Op_OUTPUT_CLOSE_ARRAY*/ At_None,
255  /*Op_OUTPUT_CLOSE_ELEM*/ At_None,
256  /*Op_OUTPUT_CLOSE*/ At_None,
257  /*Op_OUTPUT_ADD_SINK*/ At_None,
258 
259  /*Op_KEEP_RESULT*/ At_ResultName,
260  /*Op_SELECT_PARAMETER*/ At_None,
261  /*Op_SELECT_LAST_RESULT*/ At_None,
262  /*Op_SELECT_KEPT_RESULT*/ At_ResultName,
263 
264  /*Op_OPEN_ITER_LAST_RESULT*/ At_None,
265  /*Op_OPEN_ITER_KEPT_RESULT*/ At_ResultName,
266  /*Op_OPEN_ITER_PATH*/ At_Path,
267  /*Op_OPEN_ITER_TUPLESET*/ At_TupleSet,
268  /*Op_NEXT*/ At_None,
269 
270  /*Op_SUB_FRAME_OPEN*/ At_SubroutineSignature,
271  /*Op_SUB_ARG_CONST*/ At_Constant,
272  /*Op_SUB_ARG_PATH*/ At_Path,
273  /*Op_SUB_ARG_LOOPCNT*/ At_None,
274  /*Op_SUB_ARG_SEL_IDX*/ At_SelectedColumnIdx,
275  /*Op_SUB_ARG_SEL_NAM*/ At_ColumnName,
276  /*Op_SUB_ARG_ITR_IDX*/ At_IteratorColumnIdx,
277  /*Op_SUB_ARG_ITR_NAM*/ At_ColumnName,
278  /*Op_SUB_FRAME_CLOSE*/ At_None,
279 
280  /*Op_SCOPE_OPEN*/ At_None,
281  /*Op_SCOPE_RESTORE*/ At_None,
282 
283  /*Op_DBSTM_START*/ At_Statement,
284  /*Op_DBSTM_BIND_CONST*/ At_Constant,
285  /*Op_DBSTM_BIND_PATH*/ At_Path,
286  /*Op_DBSTM_BIND_LOOPCNT*/ At_None,
287  /*Op_DBSTM_BIND_SEL_IDX*/ At_SelectedColumnIdx,
288  /*Op_DBSTM_BIND_SEL_NAM*/ At_ColumnName,
289  /*Op_DBSTM_BIND_ITR_IDX*/ At_IteratorColumnIdx,
290  /*Op_DBSTM_BIND_ITR_NAM*/ At_ColumnName,
291  /*Op_DBSTM_HINT*/ At_Hint,
292  /*Op_DBSTM_EXEC*/ At_None,
293 
294  /*Op_RESULT_SET_INIT*/ At_None,
295  /*Op_RESULT_CONSTRAINT_UNIQUE*/ At_None,
296  /*Op_RESULT_CONSTRAINT_NONEMPTY*/At_None,
297 
298  /*Op_NOP*/ At_None
299  };
300  return ar[i];
301  }
302 
305  enum CondCode
306  {
307  Co_ALWAYS, //< execute always
308  Co_IF_COND, //< execute, if cond flag set to true
309  Co_NOT_IF_COND //< execute, if cond flag set to false
310  };
311 
313  static const char* condCodeName( CondCode i)
314  {
315  static const char* ar[] =
316  {
317  "",
318  "IF_COND",
319  "NOT_IF_COND"
320  };
321  return ar[i];
322  }
324  typedef boost::uint32_t ArgumentIndex;
326  typedef boost::uint32_t Address;
328  typedef boost::uint32_t Instruction;
329 
335  static Instruction instruction( CondCode cond, OpCode opcode, unsigned int arg=0)
336  {
337  Instruction rt = 0;
338  if ((unsigned int)cond > Max_CondCode) throw std::runtime_error( "VM instruction condition code out of range");
339  rt |= (Instruction)cond << Shift_CondCode;
340  if ((unsigned int)opcode > Max_OpCode) throw std::runtime_error( "VM instruction opcode out of range");
341  rt |= (Instruction)opcode << Shift_OpCode;
342  if (arg > Max_ArgumentIndex) throw std::runtime_error( "VM instruction parameter reference out of range");
343  rt |= (arg << Shift_ArgumentIndex);
344  return rt;
345  }
350  static Instruction instruction( OpCode opcode, unsigned int arg=0)
351  {
352  return instruction( Co_ALWAYS, opcode, arg);
353  }
354 
357  static CondCode condCode( const Instruction& instr) {return static_cast<CondCode>((unsigned int)(instr&Mask_CondCode) >> Shift_CondCode);}
360  static OpCode opCode( const Instruction& instr) {return static_cast<OpCode>((unsigned int)(instr&Mask_OpCode) >> Shift_OpCode);}
363  static ArgumentIndex argumentIndex( const Instruction& instr) {return static_cast<ArgumentIndex>((unsigned int)(instr&Mask_ArgumentIndex) >> Shift_ArgumentIndex);}
364 
368  static void printProgramRaw( std::ostream& out, const std::vector<Instruction>& prg)
369  {
370  std::vector<Instruction>::const_iterator pi = prg.begin(), pe = prg.end();
371  unsigned int adr = 0;
372  for (; pi != pe; ++pi,++adr)
373  {
374  CondCode cc = condCode( *pi);
375  OpCode oc = opCode( *pi);
376  ArgumentType at = argumentType( oc);
377  ArgumentIndex ai = argumentIndex( *pi);
378  out << "[" << adr << "] "<< condCodeName( cc) << " " << opCodeName( oc) << " ";
379  if (at != At_None)
380  {
381  out << argumentTypeName(at) << " " << ai;
382  }
383  out << std::endl;
384  }
385  }
386 
389  static std::string instructionstr( const Instruction& instr)
390  {
391  std::ostringstream out;
392  CondCode cc = condCode( instr);
393  OpCode oc = opCode( instr);
394  ArgumentType at = argumentType( oc);
395  ArgumentIndex ai = argumentIndex( instr);
396 
397  out << condCodeName( cc) << " " << opCodeName( oc) << " ";
398  if (at != At_None)
399  {
400  out << argumentTypeName(at) << " " << ai;
401  }
402  return out.str();
403  }
404 
405 private:
406  enum {
407  BitCnt_OpCode=6, Shift_OpCode=26, //< location and size of the operation code in the instruction
408  BitCnt_CondCode=2, Shift_CondCode=24, //< location and size of the condition code in the instruction
409  BitCnt_ArgumentIndex=20,Shift_ArgumentIndex=0 //< location and size of the argument index in the instruction
410  };
411 public:
412  enum {
413  Max_OpCode=((1<<BitCnt_OpCode)-1), //< maximum value of the operation code in the instruction
414  Max_CondCode=((1<<BitCnt_CondCode)-1), //< maximum value of the condition code in the instruction
415  Max_ArgumentIndex=((1<<BitCnt_ArgumentIndex)-1) //< maximum value of the argument index in the instruction
416  };
417 private:
418  enum {
419  Mask_OpCode=(Max_OpCode << Shift_OpCode), //< separation bit mask of the operation code in the instruction
420  Mask_CondCode=(Max_CondCode << Shift_CondCode), //< separation bit mask of the condition code in the instruction
421  Mask_ArgumentIndex=(Max_ArgumentIndex << Shift_ArgumentIndex) //< separation bit mask of the argument index in the instruction
422  };
423 };
424 
425 }}}//namespace
426 #endif
427 
Definition: instructionSet.hpp:413
Definition: instructionSet.hpp:307
Definition: instructionSet.hpp:206
Definition: instructionSet.hpp:105
Definition: instructionSet.hpp:407
Definition: instructionSet.hpp:308
Definition: instructionSet.hpp:58
Definition: instructionSet.hpp:80
Definition: instructionSet.hpp:108
Definition: instructionSet.hpp:60
static Instruction instruction(OpCode opcode, unsigned int arg=0)
Build an instruction from its parts (no condition -> always executed)
Definition: instructionSet.hpp:350
static void printProgramRaw(std::ostream &out, const std::vector< Instruction > &prg)
Print the program code without any symbolic information that is not available here.
Definition: instructionSet.hpp:368
CondCode
Enumeration of conditional codes.
Definition: instructionSet.hpp:305
boost::uint32_t Address
Address in program code.
Definition: instructionSet.hpp:326
boost::uint32_t Instruction
Instruction.
Definition: instructionSet.hpp:328
Definition: instructionSet.hpp:200
Definition: instructionSet.hpp:208
Definition: instructionSet.hpp:203
boost::uint32_t ArgumentIndex
Index of an argument.
Definition: instructionSet.hpp:324
static std::string instructionstr(const Instruction &instr)
Get the instruction as string.
Definition: instructionSet.hpp:389
Definition: instructionSet.hpp:59
ArgumentType
Enumeration of argument types.
Definition: instructionSet.hpp:196
static Instruction instruction(CondCode cond, OpCode opcode, unsigned int arg=0)
Build an instruction from its parts.
Definition: instructionSet.hpp:335
Definition: instructionSet.hpp:198
Definition: instructionSet.hpp:205
static const char * opCodeName(OpCode i)
Definition: instructionSet.hpp:127
Definition: instructionSet.hpp:309
Definition: instructionSet.hpp:201
Definition: instructionSet.hpp:125
Definition: instructionSet.hpp:104
Definition: instructionSet.hpp:414
Definition: instructionSet.hpp:419
Definition: instructionSet.hpp:407
Definition: instructionSet.hpp:202
Definition: instructionSet.hpp:408
Definition: instructionSet.hpp:64
static CondCode condCode(const Instruction &instr)
Get the condition code of an instruction (defining on which condition the instruction is executed) ...
Definition: instructionSet.hpp:357
static ArgumentIndex argumentIndex(const Instruction &instr)
Get the argument index of the instruction (addressing the argument depending on the argument type of ...
Definition: instructionSet.hpp:363
Definition: instructionSet.hpp:116
Enumeration of instructions for the transaction VM with some static functions on them.
Definition: instructionSet.hpp:50
static ArgumentType argumentType(OpCode i)
get the argument type of an operation
Definition: instructionSet.hpp:235
Definition: instructionSet.hpp:90
static const char * condCodeName(CondCode i)
Get the name of a conditional code.
Definition: instructionSet.hpp:313
static OpCode opCode(const Instruction &instr)
Get the operation code of an instruction (defining what is done on execution)
Definition: instructionSet.hpp:360
Definition: instructionSet.hpp:204
OpCode
Implemented operation codes of the VM.
Definition: instructionSet.hpp:55
Definition: instructionSet.hpp:117
Definition: instructionSet.hpp:420
Definition: instructionSet.hpp:199
static const char * argumentTypeName(ArgumentType i)
Get the name of an argument type.
Definition: instructionSet.hpp:214
Definition: instructionSet.hpp:408
Definition: instructionSet.hpp:73