00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "fennel/common/CommonPreamble.h"
00024 #include "fennel/calculator/InstructionCommon.h"
00025 #include "fennel/calculator/CalcAssembler.h"
00026
00027 #include <strstream>
00028 #include "boost/cast.hpp"
00029
00030 FENNEL_BEGIN_CPPFILE("$Id: //open/dev/fennel/calculator/CalcAssembler.cpp#3 $");
00031
00032 using namespace std;
00033
00034 CalcAssembler::~CalcAssembler()
00035 {
00036 for (uint i = RegisterReference::EFirstSet;
00037 i < RegisterReference::ELastSet;
00038 i++)
00039 {
00040 if (mCalc->mRegisterSetBinding[i] == NULL) {
00041
00042
00043 if (mBuffers[i]) {
00044 delete[] mBuffers[i];
00045 }
00046 if (mRegisterTupleData[i]) {
00047 delete mRegisterTupleData[i];
00048 }
00049 }
00050 }
00051 }
00052
00053 void CalcAssembler::init()
00054 {
00055 mCurrentRegSet = RegisterReference::EUnknown;
00056 mLiteralIndex = 0;
00057 mMaxPC = 0;
00058
00059
00060 for (uint i = RegisterReference::EFirstSet;
00061 i < RegisterReference::ELastSet;
00062 i++)
00063 {
00064 mRegisterSetDescriptor[i].clear();
00065 mRegisterTupleData[i] = NULL;
00066 mBuffers[i] = NULL;
00067 }
00068 }
00069
00070 int CalcAssembler::assemble(const char* program)
00071 {
00072 int res = 0;
00073 istringstream istr(program);
00074 mLexer.switch_streams(&istr, 0);
00075 try {
00076 assemble();
00077 } catch (CalcAssemblerException& ex) {
00078 ex.setCode(program);
00079 throw ex;
00080 }
00081
00082 return res;
00083 }
00084
00085 int CalcAssembler::assemble()
00086 {
00087 int res = 0;
00088 try {
00089 mCalc->mIsAssembling = true;
00090 res = CalcYYparse((void*) this);
00091 if (res != 0) {
00092 throw CalcAssemblerException(
00093 "Error assembling program", getLexer().getLocation());
00094 }
00095
00096
00097
00098 checkPC(mMaxPC, mMaxPCLoc);
00099 } catch (CalcAssemblerException& ex) {
00100 if (!ex.mLocValid) {
00101 ex.setLocation(getLexer().getLocation());
00102 }
00103 throw ex;
00104 } catch (FennelExcn& ex) {
00105 throw CalcAssemblerException(ex.getMessage(), getLexer().getLocation());
00106 } catch (std::exception& ex) {
00107 throw CalcAssemblerException(ex.what(), getLexer().getLocation());
00108 }
00109
00110 return res;
00111 }
00112
00113 void CalcAssembler::setTupleDatum(
00114 StandardTypeDescriptorOrdinal type,
00115 TupleDatum& tupleDatum,
00116 TupleAttributeDescriptor& desc ,
00117 PConstBuffer buffer)
00118 {
00119 tupleDatum.pData = buffer;
00120 }
00121
00122 void CalcAssembler::setTupleDatum(
00123 StandardTypeDescriptorOrdinal type,
00124 TupleDatum& tupleDatum,
00125 TupleAttributeDescriptor& desc,
00126 double value)
00127 {
00128 switch (type) {
00129 case STANDARD_TYPE_REAL:
00130
00131 *(reinterpret_cast<float *>(const_cast<PBuffer>(tupleDatum.pData))) =
00132 boost::numeric_cast<float>(value);
00133
00134
00135
00136
00137 if ((value != 0) &&
00138 (*(reinterpret_cast<float *>(const_cast<PBuffer>(tupleDatum.pData)))
00139 == 0))
00140 {
00141 throw InvalidValueException<double>(
00142 "bad numeric cast: underflow", type, value);
00143 }
00144 break;
00145 case STANDARD_TYPE_DOUBLE:
00146 *(reinterpret_cast<double *>(const_cast<PBuffer>(tupleDatum.pData))) =
00147 boost::numeric_cast<double>(value);
00148 break;
00149 default:
00150
00151 throw InvalidValueException<double>(
00152 "Cannot assign double", type, value);
00153 }
00154 }
00155
00156 void CalcAssembler::setTupleDatum(
00157 StandardTypeDescriptorOrdinal type,
00158 TupleDatum& tupleDatum,
00159 TupleAttributeDescriptor& desc,
00160 uint64_t value)
00161 {
00162 switch (type) {
00163 case STANDARD_TYPE_INT_8:
00164 *(reinterpret_cast<int8_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00165 boost::numeric_cast<int8_t>(value);
00166 break;
00167 case STANDARD_TYPE_UINT_8:
00168 *(reinterpret_cast<uint8_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00169 boost::numeric_cast<uint8_t>(value);
00170 break;
00171 case STANDARD_TYPE_INT_16:
00172 *(reinterpret_cast<int16_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00173 boost::numeric_cast<int16_t>(value);
00174 break;
00175 case STANDARD_TYPE_UINT_16:
00176 *(reinterpret_cast<uint16_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00177 boost::numeric_cast<uint16_t>(value);
00178 break;
00179 case STANDARD_TYPE_INT_32:
00180 *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00181 boost::numeric_cast<int32_t>(value);
00182 break;
00183 case STANDARD_TYPE_UINT_32:
00184 *(reinterpret_cast<uint32_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00185 boost::numeric_cast<uint32_t>(value);
00186 break;
00187 case STANDARD_TYPE_INT_64:
00188
00189
00190 if (value > std::numeric_limits<int64_t>::max()) {
00191 throw InvalidValueException<uint64_t>(
00192 "bad numeric cast: overflow", type, value);
00193 }
00194 *(reinterpret_cast<int64_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00195 boost::numeric_cast<int64_t>(value);
00196 break;
00197 case STANDARD_TYPE_UINT_64:
00198 *(reinterpret_cast<uint64_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00199 boost::numeric_cast<uint64_t>(value);
00200 break;
00201 case STANDARD_TYPE_BOOL:
00202
00203 if (value == 1) {
00204 *(reinterpret_cast<bool *>(const_cast<PBuffer>(tupleDatum.pData))) =
00205 true;
00206 } else if (value == 0) {
00207 *(reinterpret_cast<bool *>(const_cast<PBuffer>(tupleDatum.pData))) =
00208 false;
00209 } else {
00210
00211 throw InvalidValueException<uint64_t>(
00212 "Boolean value should be 0 or 1", type, value);
00213 }
00214 break;
00215 default:
00216
00217 throw InvalidValueException<uint64_t>(
00218 "Cannot assign unsigned integer", type, value);
00219 }
00220 }
00221
00222 void CalcAssembler::setTupleDatum(
00223 StandardTypeDescriptorOrdinal type,
00224 TupleDatum& tupleDatum,
00225 TupleAttributeDescriptor& desc,
00226 int64_t value)
00227 {
00228 switch (type) {
00229 case STANDARD_TYPE_INT_8:
00230 *(reinterpret_cast<int8_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00231 boost::numeric_cast<int8_t>(value);
00232 break;
00233 case STANDARD_TYPE_INT_16:
00234 *(reinterpret_cast<int16_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00235 boost::numeric_cast<int16_t>(value);
00236 break;
00237 case STANDARD_TYPE_INT_32:
00238 *(reinterpret_cast<int32_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00239 boost::numeric_cast<int32_t>(value);
00240 break;
00241 case STANDARD_TYPE_INT_64:
00242 *(reinterpret_cast<int64_t *>(const_cast<PBuffer>(tupleDatum.pData))) =
00243 boost::numeric_cast<int64_t>(value);
00244 break;
00245 default:
00246 throw InvalidValueException<int64_t>(
00247 "Cannot assign signed integer", type, value);
00248 }
00249 }
00250
00251 void CalcAssembler::setTupleDatum(
00252 StandardTypeDescriptorOrdinal type,
00253 TupleDatum& tupleDatum,
00254 TupleAttributeDescriptor& desc,
00255 string str)
00256 {
00257 ostringstream errorStr;
00258 char* ptr = reinterpret_cast<char*>(const_cast<PBuffer>(tupleDatum.pData));
00259 switch (type) {
00260 case STANDARD_TYPE_CHAR:
00261 case STANDARD_TYPE_BINARY:
00262
00263
00264 assert(tupleDatum.cbData == desc.cbStorage);
00265
00266
00267
00268 if (str.length() != tupleDatum.cbData) {
00269 ostringstream ostr("");
00270 ostr << "String length " << str.length()
00271 << " not equal to fixed size array of length "
00272 << tupleDatum.cbData;
00273 throw FennelExcn(ostr.str());
00274 }
00275
00276
00277 memcpy(ptr, str.data(), str.length());
00278 break;
00279
00280 case STANDARD_TYPE_VARCHAR:
00281 case STANDARD_TYPE_VARBINARY:
00282
00283
00284
00285
00286 if (str.length() > desc.cbStorage) {
00287 ostringstream ostr("");
00288 ostr << "String length " << str.length()
00289 << " too long for variabled sized array of maximum length "
00290 << desc.cbStorage;
00291 throw FennelExcn(ostr.str());
00292 }
00293
00294
00295 memcpy(ptr, str.data(), str.length());
00296 tupleDatum.cbData = str.length();
00297 break;
00298
00299 default:
00300 throw InvalidValueException<string>("Cannot assign string", type, str);
00301 }
00302 }
00303
00304 void CalcAssembler::bindLiteralDone()
00305 {
00306
00307
00308 TRegisterIndex regSize = getRegisterSize(RegisterReference::ELiteral);
00309 if (mLiteralIndex != regSize) {
00310 ostringstream errorStr("");
00311 errorStr << "Error binding literals: " << regSize
00312 << " literal registers, only " << mLiteralIndex
00313 << " registers bound";
00314 throw CalcAssemblerException(errorStr.str(), getLexer().getLocation());
00315 }
00316 }
00317
00318 void CalcAssembler::selectRegisterSet(RegisterReference::ERegisterSet setIndex)
00319 {
00320 mCurrentRegSet = setIndex;
00321 }
00322
00323 StandardTypeDescriptorOrdinal CalcAssembler::getRegisterType(
00324 RegisterReference::ERegisterSet setIndex,
00325 TRegisterIndex regIndex)
00326 {
00327 RegisterReference* regRef = getRegister(setIndex, regIndex);
00328 assert(regRef != NULL);
00329 return regRef->type();
00330 }
00331
00332 RegisterReference* CalcAssembler::getRegister(
00333 RegisterReference::ERegisterSet setIndex,
00334 TRegisterIndex regIndex)
00335 {
00336 assert(setIndex < RegisterReference::ELastSet);
00337 TRegisterIndex size = getRegisterSize(setIndex);
00338 if (regIndex >= size) {
00339 ostringstream errorStr("");
00340 errorStr << "Register index " << regIndex << " out of bounds.";
00341 errorStr << " Register set " << RegisterReference::getSetName(setIndex)
00342 << " has " << size << " registers.";
00343 throw CalcAssemblerException(errorStr.str(), getLexer().getLocation());
00344 }
00345 return mCalc->mRegisterRef[setIndex][regIndex];
00346 }
00347
00348 TRegisterIndex CalcAssembler::getRegisterSize(
00349 RegisterReference::ERegisterSet setIndex)
00350 {
00351 assert(setIndex < RegisterReference::ELastSet);
00352 return mCalc->mRegisterRef[setIndex].size();
00353 }
00354
00355 TupleData* CalcAssembler::getTupleData(RegisterReference::ERegisterSet setIndex)
00356 {
00357 assert(setIndex < RegisterReference::ELastSet);
00358 return mRegisterTupleData[setIndex];
00359 }
00360
00361 TupleDescriptor& CalcAssembler::getTupleDescriptor(
00362 RegisterReference::ERegisterSet setIndex)
00363 {
00364 assert(setIndex < RegisterReference::ELastSet);
00365 return mRegisterSetDescriptor[setIndex];
00366 }
00367
00368
00369 RegisterReference* CalcAssembler::createRegisterReference(
00370 RegisterReference::ERegisterSet setIndex,
00371 TRegisterIndex regIndex,
00372 StandardTypeDescriptorOrdinal regType)
00373 {
00374
00375 RegisterReference* regRef = NULL;
00376 switch (regType) {
00377 case STANDARD_TYPE_INT_8:
00378 regRef = new RegisterRef<int8_t>(setIndex, regIndex, regType);
00379 break;
00380 case STANDARD_TYPE_UINT_8:
00381 regRef = new RegisterRef<uint8_t>(setIndex, regIndex, regType);
00382 break;
00383 case STANDARD_TYPE_INT_16:
00384 regRef = new RegisterRef<int16_t>(setIndex, regIndex, regType);
00385 break;
00386 case STANDARD_TYPE_UINT_16:
00387 regRef = new RegisterRef<uint16_t>(setIndex, regIndex, regType);
00388 break;
00389 case STANDARD_TYPE_INT_32:
00390 regRef = new RegisterRef<int32_t>(setIndex, regIndex, regType);
00391 break;
00392 case STANDARD_TYPE_UINT_32:
00393 regRef = new RegisterRef<uint32_t>(setIndex, regIndex, regType);
00394 break;
00395 case STANDARD_TYPE_INT_64:
00396 regRef = new RegisterRef<int64_t>(setIndex, regIndex, regType);
00397 break;
00398 case STANDARD_TYPE_UINT_64:
00399 regRef = new RegisterRef<uint64_t>(setIndex, regIndex, regType);
00400 break;
00401 case STANDARD_TYPE_REAL:
00402 regRef = new RegisterRef<float>(setIndex, regIndex, regType);
00403 break;
00404 case STANDARD_TYPE_DOUBLE:
00405 regRef = new RegisterRef<double>(setIndex, regIndex, regType);
00406 break;
00407 case STANDARD_TYPE_BOOL:
00408 regRef = new RegisterRef<bool>(setIndex, regIndex, regType);
00409 break;
00410 case STANDARD_TYPE_CHAR:
00411 case STANDARD_TYPE_VARCHAR:
00412 regRef = new RegisterRef<char*>(setIndex, regIndex, regType);
00413 break;
00414 case STANDARD_TYPE_BINARY:
00415 case STANDARD_TYPE_VARBINARY:
00416 regRef = new RegisterRef<int8_t*>(setIndex, regIndex, regType);
00417 break;
00418 default:
00419 ostringstream errorStr("");
00420 errorStr << "Error creating register reference for "
00421 << RegisterReference::toString(setIndex, regIndex) << ": ";
00422 errorStr << "Unsupported register type " << regType;
00423 throw CalcAssemblerException(errorStr.str());
00424 break;
00425 }
00426 return regRef;
00427 }
00428
00429 void CalcAssembler::addRegister(
00430 RegisterReference::ERegisterSet setIndex,
00431 StandardTypeDescriptorOrdinal regType,
00432 TupleStorageByteLength cbStorage)
00433 {
00434 assert(mCurrentRegSet < RegisterReference::ELastSet);
00435 bool isNullable = true;
00436
00437
00438 StoredTypeDescriptor const &typeDesc = mTypeFactory.newDataType(regType);
00439 getTupleDescriptor(mCurrentRegSet).push_back(
00440 TupleAttributeDescriptor(typeDesc, isNullable, cbStorage));
00441
00442
00443 TRegisterIndex regIndex = mCalc->mRegisterRef[setIndex].size();
00444 RegisterReference* regRef =
00445 createRegisterReference(setIndex, regIndex, regType);
00446 mCalc->appendRegRef(regRef);
00447 }
00448
00449 void CalcAssembler::addRegister(
00450 StandardTypeDescriptorOrdinal const regType,
00451 TupleStorageByteLength cbStorage)
00452 {
00453 addRegister(mCurrentRegSet, regType, cbStorage);
00454 }
00455
00456 TupleData* CalcAssembler::createTupleData(
00457 TupleDescriptor const& tupleDesc,
00458 FixedBuffer** buf)
00459 {
00460 assert(buf != NULL);
00461
00462
00463
00464 TupleAccessor tupleAccessor;
00465 tupleAccessor.compute(tupleDesc, TUPLE_FORMAT_ALL_FIXED);
00466
00467 int maxByteCount = tupleAccessor.getMaxByteCount();
00468
00469
00470 *buf = new FixedBuffer[maxByteCount];
00471
00472
00473 memset(*buf, 0, maxByteCount);
00474
00475
00476 tupleAccessor.setCurrentTupleBuf(*buf, false);
00477
00478
00479 TupleData* pTupleData = new TupleData(tupleDesc);
00480
00481
00482 tupleAccessor.unmarshal(*pTupleData);
00483 return pTupleData;
00484 }
00485
00486
00487 void CalcAssembler::allocateTuples()
00488 {
00489
00490 for (uint reg = RegisterReference::EFirstSet;
00491 reg < RegisterReference::ELastSet;
00492 reg++)
00493 {
00494
00495 assert(mRegisterTupleData[reg] == NULL);
00496 assert(mBuffers[reg] == NULL);
00497
00498 if (reg == RegisterReference::ELiteral ||
00499 reg == RegisterReference::EStatus ||
00500 reg == RegisterReference::ELocal)
00501 {
00502
00503 mRegisterTupleData[reg] = createTupleData(
00504 mRegisterSetDescriptor[reg],
00505 &mBuffers[reg]);
00506 }
00507
00508
00509 }
00510 }
00511
00512 void CalcAssembler::bindRegisters()
00513 {
00514
00515 RegisterReference::ERegisterSet reg;
00516
00517
00518 reg = RegisterReference::ELiteral;
00519 mCalc->mBuffers.push_back(mBuffers[reg]);
00520 mCalc->bind(reg, getTupleData(reg), getTupleDescriptor(reg));
00521
00522
00523 reg = RegisterReference::EStatus;
00524 mCalc->mBuffers.push_back(mBuffers[reg]);
00525 mCalc->bind(reg, getTupleData(reg), getTupleDescriptor(reg));
00526
00527
00528 reg = RegisterReference::ELocal;
00529 mCalc->mBuffers.push_back(mBuffers[reg]);
00530 mCalc->bind(reg, getTupleData(reg), getTupleDescriptor(reg));
00531
00532
00533
00534 reg = RegisterReference::EInput;
00535 mCalc->mRegisterSetDescriptor[reg] =
00536 new TupleDescriptor(getTupleDescriptor(reg));
00537
00538 reg = RegisterReference::EOutput;
00539 mCalc->mRegisterSetDescriptor[reg] =
00540 new TupleDescriptor(getTupleDescriptor(reg));
00541 }
00542
00543 void CalcAssembler::addInstruction(Instruction* inst)
00544 {
00545 assert(inst != NULL);
00546 mCalc->appendInstruction(inst);
00547 }
00548
00549 FENNEL_END_CPPFILE("$Id: //open/dev/fennel/calculator/CalcAssembler.cpp#3 $");
00550
00551