18 #include <ndb_global.h>
19 #include "NdbInterpretedCode.hpp"
20 #include "Interpreter.hpp"
21 #include "NdbDictionaryImpl.hpp"
41 Uint32 *buffer, Uint32 buffer_word_size) :
44 m_buffer_length(buffer_word_size),
46 m_number_of_labels(0),
49 m_last_meta_pos(m_buffer_length),
50 m_instructions_length(0),
51 m_first_sub_instruction_pos(0),
52 m_available_length(m_buffer_length),
56 m_table_impl= & NdbTableImpl::getImpl(*table);
60 NdbInterpretedCode::~NdbInterpretedCode()
62 if (m_internal_buffer != NULL)
64 delete [] m_internal_buffer;
71 NdbInterpretedCode::error(Uint32
code)
85 NdbInterpretedCode::have_space_for(Uint32 wordsRequired)
87 assert(m_last_meta_pos <= m_buffer_length);
88 assert(m_last_meta_pos >= m_instructions_length);
89 assert(m_available_length == m_last_meta_pos - m_instructions_length);
90 if (likely(m_available_length >= wordsRequired))
93 if ((m_internal_buffer != NULL) || (m_buffer_length == 0))
95 Uint32 newSize= m_buffer_length;
96 const Uint32 extraRequired= wordsRequired - m_available_length;
106 newSize= newSize << 1;
107 }
while (((newSize - m_buffer_length) < extraRequired) &&
108 (newSize < MaxDynamicBufSize));
110 if (newSize > MaxDynamicBufSize)
111 newSize= MaxDynamicBufSize;
114 if ((newSize - m_buffer_length) >= extraRequired)
116 Uint32 *newBuf=
new Uint32[ newSize ];
120 Uint32 metaInfoWords= m_buffer_length - m_last_meta_pos;
121 Uint32 newLastMetaInfoPos= newSize - metaInfoWords;
123 if (m_buffer_length > 0)
126 memcpy(newBuf, m_internal_buffer, m_instructions_length << 2);
129 memcpy(&newBuf[ newLastMetaInfoPos ],
130 &m_buffer[ m_last_meta_pos ],
133 delete [] m_internal_buffer;
136 m_buffer= m_internal_buffer= newBuf;
137 m_available_length+= (newSize - m_buffer_length);
138 m_buffer_length= newSize;
139 m_last_meta_pos= newLastMetaInfoPos;
149 NdbInterpretedCode::add1(Uint32 x1)
151 if (unlikely(! have_space_for(1)))
152 return error(TooManyInstructions);
154 Uint32 current = m_instructions_length;
155 m_buffer[current ] = x1;
156 m_instructions_length = current + 1;
157 m_available_length--;
162 NdbInterpretedCode::add2(Uint32 x1, Uint32 x2)
164 if (unlikely(! have_space_for(2)))
165 return error(TooManyInstructions);
166 Uint32 current = m_instructions_length;
167 m_buffer[current ] = x1;
168 m_buffer[current + 1] = x2;
169 m_instructions_length = current + 2;
170 m_available_length-= 2;
175 NdbInterpretedCode::add3(Uint32 x1, Uint32 x2, Uint32 x3)
177 if (unlikely(! have_space_for(3)))
178 return error(TooManyInstructions);
179 Uint32 current = m_instructions_length;
180 m_buffer[current ] = x1;
181 m_buffer[current + 1] = x2;
182 m_buffer[current + 2] = x3;
183 m_instructions_length = current + 3;
184 m_available_length-= 3;
189 NdbInterpretedCode::addN(Uint32 *data, Uint32 length)
191 if (unlikely(! have_space_for(length)))
192 return error(TooManyInstructions);
197 memcpy(&m_buffer[m_instructions_length],
201 m_instructions_length+= length;
202 m_available_length-= length;
208 NdbInterpretedCode::addMeta(CodeMetaInfo& info)
210 if (unlikely(! have_space_for(CODEMETAINFO_WORDS)))
211 return error(TooManyInstructions);
213 m_buffer[--m_last_meta_pos]= (Uint32)info.number << 16 | info.type;
214 m_buffer[--m_last_meta_pos]= info.firstInstrPos;
216 m_available_length-= CODEMETAINFO_WORDS;
222 NdbInterpretedCode::add_reg(Uint32 RegDest,
223 Uint32 RegSource1, Uint32 RegSource2)
225 return add1(Interpreter::Add(RegDest % MaxReg, RegSource1 % MaxReg,
226 RegSource2 % MaxReg));
230 NdbInterpretedCode::sub_reg(Uint32 RegDest,
231 Uint32 RegSource1, Uint32 RegSource2)
233 return add1(Interpreter::Sub(RegDest % MaxReg, RegSource1 % MaxReg,
234 RegSource2 % MaxReg));
238 NdbInterpretedCode::load_const_u32(Uint32 RegDest, Uint32 Constant)
240 return add2(Interpreter::LoadConst32(RegDest % MaxReg), Constant);
244 NdbInterpretedCode::load_const_u64(Uint32 RegDest, Uint64 Constant)
251 return add3(Interpreter::LoadConst64(RegDest % MaxReg), val32[0], val32[1]);
255 NdbInterpretedCode::load_const_null(Uint32 RegDest)
257 return add1(Interpreter::LoadNull(RegDest % MaxReg));
261 NdbInterpretedCode::load_const_u16(Uint32 RegDest, Uint32 Constant)
263 return add1(Interpreter::LoadConst16((RegDest % MaxReg), Constant));
267 NdbInterpretedCode::read_attr_impl(
const NdbColumnImpl *c, Uint32 RegDest)
269 if (c->m_storageType == NDB_STORAGETYPE_DISK)
275 NdbInterpretedCode::read_attr(Uint32 RegDest, Uint32 attrId)
277 if (unlikely(m_table_impl == NULL))
281 if (unlikely(c == NULL))
282 return error(BadAttributeId);
283 return read_attr_impl(c, RegDest);
287 NdbInterpretedCode::read_attr(Uint32 RegDest,
290 if (unlikely(m_table_impl == NULL))
294 return read_attr_impl(&NdbColumnImpl::getImpl(*column), RegDest);
298 NdbInterpretedCode::write_attr_impl(
const NdbColumnImpl *c, Uint32 RegSource)
300 if (c->m_storageType == NDB_STORAGETYPE_DISK)
302 return add1(Interpreter::Write(c->m_attrId, RegSource % MaxReg));
306 NdbInterpretedCode::write_attr(Uint32 attrId, Uint32 RegSource)
308 if (unlikely(m_table_impl == NULL))
312 if (unlikely(c == NULL))
313 return error(BadAttributeId);
314 return write_attr_impl(c, RegSource);
321 if (unlikely(m_table_impl == NULL))
325 return write_attr_impl(&NdbColumnImpl::getImpl(*column), RegSource);
329 NdbInterpretedCode::def_label(
int LabelNum)
332 (Uint32)LabelNum > MaxLabels)
333 return error(BadLabelNum);
335 m_number_of_labels++;
340 info.number= LabelNum;
341 info.firstInstrPos= m_instructions_length;
344 return addMeta(info);
348 NdbInterpretedCode::add_branch(Uint32 instruction, Uint32 Label)
355 if (unlikely(Label > 0xffff))
356 return error(BranchToBadLabel);
357 return add1(instruction | Label << 16);
361 NdbInterpretedCode::branch_label(Uint32 Label)
363 return add_branch(Interpreter::BRANCH, Label);
373 NdbInterpretedCode::branch_ge(Uint32 RegLvalue, Uint32 RegRvalue,
376 Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_GE_REG_REG,
377 RegRvalue, RegLvalue);
378 return add_branch(instr, Label);
382 NdbInterpretedCode::branch_gt(Uint32 RegLvalue, Uint32 RegRvalue,
385 Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_GT_REG_REG,
386 RegRvalue, RegLvalue);
387 return add_branch(instr, Label);
391 NdbInterpretedCode::branch_le(Uint32 RegLvalue, Uint32 RegRvalue,
394 Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_LE_REG_REG,
395 RegRvalue, RegLvalue);
396 return add_branch(instr, Label);
400 NdbInterpretedCode::branch_lt(Uint32 RegLvalue, Uint32 RegRvalue,
403 Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_LT_REG_REG,
404 RegRvalue, RegLvalue);
405 return add_branch(instr, Label);
409 NdbInterpretedCode::branch_eq(Uint32 RegLvalue, Uint32 RegRvalue,
412 Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_EQ_REG_REG,
413 RegLvalue, RegRvalue);
414 return add_branch(instr, Label);
418 NdbInterpretedCode::branch_ne(Uint32 RegLvalue, Uint32 RegRvalue,
421 Uint32 instr = Interpreter::Branch(Interpreter::BRANCH_NE_REG_REG,
422 RegLvalue, RegRvalue);
423 return add_branch(instr, Label);
427 NdbInterpretedCode::branch_ne_null(Uint32 RegLvalue, Uint32 Label)
430 (((RegLvalue % MaxReg) << 6) | Interpreter::BRANCH_REG_NE_NULL, Label);
434 NdbInterpretedCode::branch_eq_null(Uint32 RegLvalue, Uint32 Label)
437 (((RegLvalue % MaxReg) << 6) | Interpreter::BRANCH_REG_EQ_NULL, Label);
441 NdbInterpretedCode::branch_col_eq_null(Uint32 attrId, Uint32 Label)
445 if (unlikely(m_table_impl == NULL))
450 if (unlikely(c == NULL))
451 return error(BadAttributeId);
453 if (c->m_storageType == NDB_STORAGETYPE_DISK)
457 if ((res= add_branch(Interpreter::BRANCH_ATTR_EQ_NULL, Label)) !=0)
461 return add1(Interpreter::BranchCol_2(attrId));
465 NdbInterpretedCode::branch_col_ne_null(Uint32 attrId, Uint32 Label)
469 if (unlikely(m_table_impl == NULL))
474 if (unlikely(c == NULL))
475 return error(BadAttributeId);
477 if (c->m_storageType == NDB_STORAGETYPE_DISK)
481 if ((res= add_branch(Interpreter::BRANCH_ATTR_NE_NULL, Label)) !=0)
485 return add1(Interpreter::BranchCol_2(attrId));
489 NdbInterpretedCode::branch_col(Uint32 branch_type,
495 DBUG_ENTER(
"NdbInterpretedCode::branch_col");
496 DBUG_PRINT(
"enter", (
"type: %u col:%u val: 0x%lx len: %u label: %u",
497 branch_type, attrId, (
long) val, len, Label));
499 DBUG_DUMP(
"value", (uchar*)val, len);
501 DBUG_PRINT(
"info", (
"value == NULL"));
503 Interpreter::BinaryCondition c=
504 (Interpreter::BinaryCondition)branch_type;
506 if (unlikely(m_table_impl == NULL))
508 DBUG_RETURN(error(4538));
511 m_table_impl->getColumn(attrId);
514 DBUG_RETURN(error(BadAttributeId));
517 Uint32 lastWordMask= ~0;
521 if (! col->getStringType())
524 if (col->
getType() == NDB_TYPE_BIT)
530 Uint32 lastWordBits= bitLen & 0x1F;
532 lastWordMask= (1 << lastWordBits) -1;
534 len= col->m_attrSize * col->m_arraySize;
542 if ((branch_type != Interpreter::LIKE) &&
543 (branch_type != Interpreter::NOT_LIKE))
545 if (! col->get_var_length(val, len))
547 DBUG_RETURN(error(BadLength));
553 if (col->m_storageType == NDB_STORAGETYPE_DISK)
556 if (add_branch(Interpreter::BranchCol(c, 0, 0), Label) != 0)
559 if (add1(Interpreter::BranchCol_2(attrId, len)) != 0)
563 Uint32 len2 = Interpreter::mod4(len);
564 if((len2 == len) && (lastWordMask == (Uint32)~0))
567 DBUG_RETURN(addN((Uint32*)val, len2 >> 2));
573 if (addN((Uint32*)val, len2 >> 2) != 0)
578 for (Uint32
i = 0;
i < len-len2;
i++) {
579 char* p = (
char*)&tmp;
580 p[
i] = ((
char*)val)[len2+
i];
582 DBUG_RETURN(add1((tmp & lastWordMask)));
586 NdbInterpretedCode::branch_col_eq(
const void * val,
591 return branch_col(Interpreter::EQ, attrId, val, 0, Label);
595 NdbInterpretedCode::branch_col_ne(
const void * val,
600 return branch_col(Interpreter::NE, attrId, val, 0, Label);
604 NdbInterpretedCode::branch_col_lt(
const void * val,
609 return branch_col(Interpreter::LT, attrId, val, 0, Label);
613 NdbInterpretedCode::branch_col_le(
const void * val,
618 return branch_col(Interpreter::LE, attrId, val, 0, Label);
622 NdbInterpretedCode::branch_col_gt(
const void * val,
627 return branch_col(Interpreter::GT, attrId, val, 0, Label);
631 NdbInterpretedCode::branch_col_ge(
const void * val,
636 return branch_col(Interpreter::GE, attrId, val, 0, Label);
640 NdbInterpretedCode::branch_col_like(
const void * val,
645 return branch_col(Interpreter::LIKE, attrId, val, len, Label);
649 NdbInterpretedCode::branch_col_notlike(
const void * val,
654 return branch_col(Interpreter::NOT_LIKE, attrId, val, len, Label);
658 NdbInterpretedCode::branch_col_and_mask_eq_mask(
const void * mask,
663 return branch_col(Interpreter::AND_EQ_MASK, attrId, mask, 0, Label);
667 NdbInterpretedCode::branch_col_and_mask_ne_mask(
const void * mask,
672 return branch_col(Interpreter::AND_NE_MASK, attrId, mask, 0, Label);
676 NdbInterpretedCode::branch_col_and_mask_eq_zero(
const void * mask,
681 return branch_col(Interpreter::AND_EQ_ZERO, attrId, mask, 0, Label);
685 NdbInterpretedCode::branch_col_and_mask_ne_zero(
const void * mask,
690 return branch_col(Interpreter::AND_NE_ZERO, attrId, mask, 0, Label);
694 NdbInterpretedCode::interpret_exit_ok()
696 return add1(Interpreter::EXIT_OK);
700 NdbInterpretedCode::interpret_exit_nok(Uint32 ErrorCode)
702 return add1((ErrorCode << 16) | Interpreter::EXIT_REFUSE);
706 NdbInterpretedCode::interpret_exit_nok()
708 return add1((626 << 16) | Interpreter::EXIT_REFUSE);
712 NdbInterpretedCode::interpret_exit_last_row()
714 return add1(Interpreter::EXIT_OK_LAST);
718 NdbInterpretedCode::add_val(Uint32 attrId, Uint32 aValue)
722 if ((res= read_attr(6, attrId) != 0))
729 if (aValue < (1 << 16))
731 if ((res= load_const_u16(7, aValue)) != 0)
736 if ((res= load_const_u32(7, aValue)) != 0)
741 if ((res= add_reg(7, 6, 7)) != 0)
745 return write_attr(attrId, 7);
750 NdbInterpretedCode::add_val(Uint32 attrId, Uint64 aValue)
754 if ((res= read_attr(6, attrId) != 0))
761 if ((aValue >> 32) == 0)
763 if (aValue < (1 << 16))
765 if ((res= load_const_u16(7, (Uint32)aValue)) != 0)
770 if ((res= load_const_u32(7, (Uint32)aValue)) != 0)
775 if ((res= load_const_u64(7, aValue)) != 0)
779 if ((res= add_reg(7, 6, 7)) != 0)
783 return write_attr(attrId, 7);
788 NdbInterpretedCode::sub_val(Uint32 attrId, Uint32 aValue)
792 if ((res= read_attr(6, attrId) != 0))
799 if (aValue < (1 << 16))
801 if ((res= load_const_u16(7, aValue)) != 0)
806 if ((res= load_const_u32(7, aValue)) != 0)
811 if ((res= sub_reg(7, 6, 7)) != 0)
815 return write_attr(attrId, 7);
820 NdbInterpretedCode::sub_val(Uint32 attrId, Uint64 aValue)
824 if ((res= read_attr(6, attrId) != 0))
831 if ((aValue >> 32) == 0)
833 if (aValue < (1 << 16))
835 if ((res= load_const_u16(7, (Uint32)aValue)) != 0)
840 if ((res= load_const_u32(7, (Uint32)aValue)) != 0)
846 if ((res= load_const_u64(7, aValue)) != 0)
851 if ((res= sub_reg(7, 6, 7)) != 0)
855 return write_attr(attrId, 7);
861 if (SubroutineNumber > MaxSubs)
862 return error(BadSubNumber);
864 if (m_flags & InSubroutineDef)
865 return error(BadState);
867 if (m_number_of_calls == 0)
868 return error(BadState);
871 if (m_number_of_subs == 0)
872 m_first_sub_instruction_pos= m_instructions_length;
875 m_flags|= InSubroutineDef;
879 info.type= Subroutine;
880 info.number= SubroutineNumber;
882 m_instructions_length - m_first_sub_instruction_pos;
885 return addMeta(info);
891 if (SubroutineNumber > MaxSubs)
892 return error(BadState);
894 m_number_of_calls ++;
896 return add1(Interpreter::CALL | (SubroutineNumber << 16));
902 if ((m_flags & InSubroutineDef) == 0)
903 return error(BadState);
905 m_flags&= ~(InSubroutineDef);
907 return add1(Interpreter::RETURN);
915 NdbInterpretedCode::getInfo(Uint32 number, CodeMetaInfo &info)
const
917 if (number >= (m_number_of_labels + m_number_of_subs))
920 Uint32 pos= m_buffer_length
921 - ((number+1) * CODEMETAINFO_WORDS);
923 info.number= (m_buffer[pos + 1] >> 16) & 0xffff;
924 info.type= m_buffer[pos + 1] & 0xffff;
925 info.firstInstrPos= m_buffer[pos];
935 ndberror_update(&ndberror);
942 return (m_table_impl == NULL) ?
944 m_table_impl->m_facade;
961 return (m_buffer_length - m_available_length);
969 m_table_impl = src.m_table_impl;
970 m_buffer_length = src.m_buffer_length;
975 if (m_internal_buffer!=NULL)
977 delete[] m_internal_buffer;
978 m_internal_buffer = NULL;
981 if (src.m_internal_buffer==NULL)
984 m_buffer = src.m_buffer;
988 m_buffer = m_internal_buffer =
new Uint32[m_buffer_length];
989 if (unlikely(m_internal_buffer==NULL))
993 memcpy(m_internal_buffer,
994 src.m_internal_buffer,
995 m_buffer_length*
sizeof(Uint32));
998 m_number_of_labels = src.m_number_of_labels;
999 m_number_of_subs = src.m_number_of_subs;
1000 m_number_of_calls = src.m_number_of_calls;
1001 m_last_meta_pos = src.m_last_meta_pos;
1002 m_instructions_length = src.m_instructions_length;
1003 m_first_sub_instruction_pos = src.m_first_sub_instruction_pos;
1004 m_available_length = src.m_available_length;
1005 m_flags = src.m_flags;
1006 m_error = src.m_error;
1019 NdbInterpretedCode::compareMetaInfo(
const void *va,
1022 Uint32 aWord= *(((Uint32 *) va) + 1);
1023 Uint32 bWord= *(((Uint32 *) vb) + 1);
1024 Uint16 aType= aWord & 0xffff;
1025 Uint16 bType= bWord & 0xffff;
1026 const int AFirst= -1;
1027 const int BFirst= 1;
1031 return (aType == Subroutine)? AFirst : BFirst;
1033 Uint16 aNumber= (aWord >> 16) & 0xffff;
1034 Uint16 bNumber= (bWord >> 16) & 0xffff;
1039 if (aNumber != bNumber)
1040 return (bNumber > aNumber)? BFirst : AFirst;
1049 if (m_instructions_length == 0)
1056 if (0 != (res= interpret_exit_ok()))
1060 assert (m_buffer != NULL);
1067 Uint32 numOfMetaInfos= m_number_of_labels +
1069 Uint32 sizeOfMetaInfo= numOfMetaInfos * CODEMETAINFO_WORDS;
1070 Uint32 startOfMetaInfo= m_buffer_length - sizeOfMetaInfo;
1073 qsort( &m_buffer[ startOfMetaInfo ],
1075 CODEMETAINFO_WORDS << 2,
1081 Uint32 *ip= m_buffer;
1083 Uint32
const* firstInstruction= m_buffer;
1084 Uint32
const* endOfProgram= m_buffer + m_instructions_length;
1086 while (ip < endOfProgram)
1089 nextIp= Interpreter::getInstructionPreProcessingInfo(ip,
1098 case Interpreter::NONE:
1101 case Interpreter::LABEL_ADDRESS_REPLACEMENT:
1104 Uint32 label= Interpreter::getLabel(*ip);
1106 if (label > m_number_of_labels)
1113 if (getInfo(label, info) != 0)
1119 assert(info.type == Label);
1121 Uint32 currOffset = Uint32(ip - firstInstruction);
1122 Uint32 labelOffset= info.firstInstrPos;
1124 if (labelOffset >= m_instructions_length)
1131 Uint32 patchedInstruction= (*ip) & 0xffff;
1133 if (labelOffset < currOffset)
1135 patchedInstruction |= (((currOffset - labelOffset) << 16) |
1136 ((Uint32) 1 << 31));
1139 patchedInstruction |= ((labelOffset - currOffset) <<16);
1141 *ip= patchedInstruction;
1144 case Interpreter::SUB_ADDRESS_REPLACEMENT:
1149 Uint32 subroutine= Interpreter::getLabel(*ip);
1151 if (subroutine > m_number_of_subs)
1158 if (getInfo(m_number_of_labels + subroutine, info) != 0)
1164 assert(info.type == Subroutine);
1166 Uint32 subOffset= info.firstInstrPos;
1168 if (subOffset > (m_instructions_length -
1169 m_first_sub_instruction_pos))
1178 Uint32 patchedInstruction= (*ip) & 0xffff;
1179 patchedInstruction |= subOffset << 16;
1180 *ip= patchedInstruction;
1193 m_flags |= Finalised;