hqlstack.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include "hqlstack.hpp"
  16. FuncCallStack::FuncCallStack(int size) {
  17. if(size < DEFAULTSTACKSIZE)
  18. size = DEFAULTSTACKSIZE;
  19. sp = 0;
  20. tos = size;
  21. stackbuf = (char*) malloc(tos);
  22. numToFree = 0;
  23. #ifdef __64BIT__
  24. numFpRegs = 0;
  25. for (unsigned i=0;i<MAXFPREGS;i++)
  26. fpRegs[i] = 0.0;
  27. #endif
  28. }
  29. FuncCallStack::~FuncCallStack() {
  30. if(stackbuf) {
  31. free(stackbuf);
  32. }
  33. // Free memory used by string/data parameters
  34. for(int i = 0; i < numToFree; i++) {
  35. if(toFree[i]) {
  36. free(toFree[i]);
  37. }
  38. }
  39. }
  40. unsigned FuncCallStack::getSp(){
  41. return sp;
  42. }
  43. char* FuncCallStack::getMem() {
  44. return stackbuf;
  45. }
  46. int FuncCallStack::push(unsigned len, const void * data)
  47. {
  48. int incsize = len;
  49. int inclen = align(incsize);
  50. assure(inclen);
  51. memcpy(stackbuf + sp, data, incsize);
  52. memset(stackbuf+sp+incsize, 0, inclen - incsize);
  53. sp += inclen;
  54. return sp;
  55. }
  56. int FuncCallStack::push(ITypeInfo* argType, IValue* paramValue)
  57. {
  58. unsigned len = 0;
  59. char* str;
  60. int incsize;
  61. int inclen;
  62. Owned<IValue> castParam = paramValue->castTo(argType);
  63. if(!castParam) {
  64. PrintLog("Failed to cast paramValue to argType in FuncCallStack::push");
  65. return -1;
  66. }
  67. switch (argType->getTypeCode())
  68. {
  69. case type_string:
  70. case type_data:
  71. getStringFromIValue(len, str, castParam);
  72. // For STRINGn, len doesn't need to be passed in.
  73. if(argType->getSize() == UNKNOWN_LENGTH) {
  74. push(sizeof(unsigned), &len);
  75. }
  76. push(sizeof(char *), &str);
  77. if(numToFree < MAXARGS) {
  78. toFree[numToFree++] = str;
  79. }
  80. break;
  81. case type_varstring:
  82. getStringFromIValue(len, str, castParam);
  83. push(sizeof(char *), &str);
  84. if(numToFree < MAXARGS) {
  85. toFree[numToFree++] = str;
  86. }
  87. break;
  88. case type_qstring:
  89. case type_unicode:
  90. case type_utf8:
  91. {
  92. unsigned argSize = castParam->getSize();
  93. const void * text = castParam->queryValue();
  94. str = (char *)malloc(argSize);
  95. memcpy(str, text, argSize);
  96. // For STRINGn, len doens't need to be passed in.
  97. if(argType->getSize() == UNKNOWN_LENGTH)
  98. {
  99. len = castParam->queryType()->getStringLen();
  100. push(sizeof(unsigned), &len);
  101. }
  102. push(sizeof(char *), &str);
  103. if(numToFree < MAXARGS) {
  104. toFree[numToFree++] = str;
  105. }
  106. }
  107. break;
  108. case type_varunicode:
  109. UNIMPLEMENTED;
  110. case type_real:
  111. #ifdef __64BIT__
  112. if (numFpRegs==MAXFPREGS) {
  113. PrintLog("Too many floating point registers needed in FuncCallStack::push");
  114. return -1;
  115. }
  116. char tempbuf[MMXREGSIZE];
  117. castParam->toMem(tempbuf);
  118. if (argType->getSize()<=4)
  119. fpRegs[numFpRegs++] = *(float *)&tempbuf;
  120. else
  121. fpRegs[numFpRegs++] = *(double *)&tempbuf;
  122. break;
  123. #else
  124. // fall through
  125. #endif
  126. case type_boolean:
  127. case type_int:
  128. case type_decimal:
  129. case type_date:
  130. case type_char:
  131. case type_enumerated:
  132. case type_swapint:
  133. case type_packedint:
  134. incsize = argType->getSize();
  135. inclen = align(incsize);
  136. assure(inclen);
  137. castParam->toMem(stackbuf+sp);
  138. memset(stackbuf+sp+incsize, 0, inclen - incsize);
  139. sp += inclen;
  140. break;
  141. default:
  142. //code isn't here to pass sets/datasets to external functions....
  143. return -1;
  144. }
  145. return sp;
  146. }
  147. int FuncCallStack::pushPtr(void * val)
  148. {
  149. return push(sizeof(void *), &val);
  150. }
  151. int FuncCallStack::push(char* & val) {
  152. return push(sizeof(char *), &val);
  153. }
  154. int FuncCallStack::pushRef(unsigned& val) {
  155. unsigned* valRef = &val;
  156. return push(sizeof(unsigned *), &valRef);
  157. }
  158. int FuncCallStack::pushRef(char*& val) {
  159. char** valRef = &val;
  160. return push(sizeof(char **), &valRef);
  161. }
  162. void FuncCallStack::assure(int inclen) {
  163. if(sp + inclen >= tos) {
  164. tos += INCREMENTALSIZE;
  165. stackbuf = (char *)realloc(stackbuf, tos);
  166. }
  167. }