int FuncCallStack::push(ITypeInfo* argType, IValue* paramValue) { unsigned len = 0; char* str; int incsize; int inclen; Owned<IValue> castParam = paramValue->castTo(argType); if(!castParam) { PrintLog("Failed to cast paramValue to argType in FuncCallStack::push"); return -1; } switch (argType->getTypeCode()) { case type_string: case type_data: getStringFromIValue(len, str, castParam); // For STRINGn, len doesn't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_varstring: getStringFromIValue(len, str, castParam); push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_qstring: case type_unicode: case type_utf8: { unsigned argSize = castParam->getSize(); const void * text = castParam->queryValue(); str = (char *)malloc(argSize); memcpy(str, text, argSize); // For STRINGn, len doens't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { len = castParam->queryType()->getStringLen(); push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } } break; case type_varunicode: UNIMPLEMENTED; case type_real: #ifdef __64BIT__ if (numFpRegs==MAXFPREGS) { PrintLog("Too many floating point registers needed in FuncCallStack::push"); return -1; } char tempbuf[MMXREGSIZE]; castParam->toMem(tempbuf); if (argType->getSize()<=4) fpRegs[numFpRegs++] = *(float *)&tempbuf; else fpRegs[numFpRegs++] = *(double *)&tempbuf; break; #else // fall through #endif case type_boolean: case type_int: case type_decimal: case type_date: case type_char: case type_enumerated: case type_swapint: case type_packedint: incsize = argType->getSize(); inclen = align(incsize); assure(inclen); castParam->toMem(stackbuf+sp); memset(stackbuf+sp+incsize, 0, inclen - incsize); sp += inclen; break; default: //code isn't here to pass sets/datasets to external functions.... return -1; } return sp; }
int FuncCallStack::push(ITypeInfo* argType, IHqlExpression* curParam) { unsigned len = 0; char* str; int incsize; int inclen; IValue * paramValue = curParam->queryValue(); Owned<IValue> castParam; if (paramValue) // Not all constants have a paramValue - null, all, constant records etc { castParam.setown(paramValue->castTo(argType)); if(!castParam) { PrintLog("Failed to cast paramValue to argType in FuncCallStack::push"); return -1; } } switch (argType->getTypeCode()) { case type_string: case type_data: getStringFromIValue(len, str, castParam); // For STRINGn, len doesn't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_varstring: getStringFromIValue(len, str, castParam); push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } break; case type_qstring: case type_unicode: case type_utf8: { unsigned argSize = castParam->getSize(); const void * text = castParam->queryValue(); str = (char *)malloc(argSize); memcpy(str, text, argSize); // For STRINGn, len doens't need to be passed in. if(argType->getSize() == UNKNOWN_LENGTH) { len = castParam->queryType()->getStringLen(); push(sizeof(unsigned), &len); } push(sizeof(char *), &str); if(numToFree < MAXARGS) { toFree[numToFree++] = str; } } break; case type_varunicode: UNIMPLEMENTED; case type_real: #ifdef MAXFPREGS if (numFpRegs==MAXFPREGS) { PrintLog("Too many floating point registers needed in FuncCallStack::push"); return -1; } char tempbuf[sizeof(double)]; castParam->toMem(tempbuf); #ifdef FPREG_FIXEDSIZE if (argType->getSize()<=4) fpRegs[numFpRegs++] = *(float *)&tempbuf; else fpRegs[numFpRegs++] = *(double *)&tempbuf; #else // Variable size FP registers as on arm/x64 if (argType->getSize()<=4) fpRegs[numFpRegs].f = *(float *)&tempbuf; else fpRegs[numFpRegs].d = *(double *)&tempbuf; fpSizes[numFpRegs++] = argType->getSize(); #endif break; #else // fall through if no hw regs used for params #endif case type_boolean: case type_int: case type_decimal: case type_date: case type_char: case type_enumerated: case type_swapint: case type_packedint: incsize = argType->getSize(); inclen = align(incsize); assure(inclen); castParam->toMem(stackbuf+sp); memset(stackbuf+sp+incsize, 0, inclen - incsize); sp += inclen; break; case type_row: { if (hasMeta) { try { pushMeta(curParam->queryRecordType()); } catch (IException *E) { ::Release(E); return -1; } } if (curParam->getOperator()==no_null) { // MORE - check type matches MemoryBuffer out; createConstantNullRow(out, curParam->queryRecord()); str = (char *) out.detach(); push(sizeof(char *), &str); if(numToFree < MAXARGS) toFree[numToFree++] = str; } else return -1; break; } case type_record: { try { pushMeta(curParam->queryRecordType()); } catch (IException *E) { ::Release(E); return -1; } break; } default: EclIR::dump_ir(curParam); //code isn't here to pass sets/datasets to external functions.... return -1; } return sp; }