Fennel: /home/pub/open/dev/fennel/calculator/CalcAssembler.cpp Source File (original) (raw)

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 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(tupleDatum.pData))) = 00132 boost::numeric_cast(value); 00133 00134
00135
00136
00137 if ((value != 0) && 00138 (
(reinterpret_cast<float *>(const_cast(tupleDatum.pData))) 00139 == 0)) 00140 { 00141 throw InvalidValueException( 00142 "bad numeric cast: underflow", type, value); 00143 } 00144 break; 00145 case STANDARD_TYPE_DOUBLE: 00146 *(reinterpret_cast<double *>(const_cast(tupleDatum.pData))) = 00147 boost::numeric_cast(value); 00148 break; 00149 default: 00150
00151 throw InvalidValueException( 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(tupleDatum.pData))) = 00165 boost::numeric_cast(value); 00166 break; 00167 case STANDARD_TYPE_UINT_8: 00168 *(reinterpret_cast<uint8_t *>(const_cast(tupleDatum.pData))) = 00169 boost::numeric_cast(value); 00170 break; 00171 case STANDARD_TYPE_INT_16: 00172 *(reinterpret_cast<int16_t *>(const_cast(tupleDatum.pData))) = 00173 boost::numeric_cast(value); 00174 break; 00175 case STANDARD_TYPE_UINT_16: 00176 *(reinterpret_cast<uint16_t *>(const_cast(tupleDatum.pData))) = 00177 boost::numeric_cast(value); 00178 break; 00179 case STANDARD_TYPE_INT_32: 00180 *(reinterpret_cast<int32_t *>(const_cast(tupleDatum.pData))) = 00181 boost::numeric_cast(value); 00182 break; 00183 case STANDARD_TYPE_UINT_32: 00184 *(reinterpret_cast<uint32_t *>(const_cast(tupleDatum.pData))) = 00185 boost::numeric_cast(value); 00186 break; 00187 case STANDARD_TYPE_INT_64: 00188
00189
00190 if (value > std::numeric_limits::max()) { 00191 throw InvalidValueException( 00192 "bad numeric cast: overflow", type, value); 00193 } 00194 *(reinterpret_cast<int64_t *>(const_cast(tupleDatum.pData))) = 00195 boost::numeric_cast(value); 00196 break; 00197 case STANDARD_TYPE_UINT_64: 00198 (reinterpret_cast<uint64_t *>(const_cast(tupleDatum.pData))) = 00199 boost::numeric_cast(value); 00200 break; 00201 case STANDARD_TYPE_BOOL: 00202
00203 if (value == 1) { 00204 (reinterpret_cast<bool *>(const_cast(tupleDatum.pData))) = 00205 true; 00206 } else if (value == 0) { 00207 (reinterpret_cast<bool *>(const_cast(tupleDatum.pData))) = 00208 false; 00209 } else { 00210
00211 throw InvalidValueException( 00212 "Boolean value should be 0 or 1", type, value); 00213 } 00214 break; 00215 default: 00216
00217 throw InvalidValueException( 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(tupleDatum.pData))) = 00231 boost::numeric_cast(value); 00232 break; 00233 case STANDARD_TYPE_INT_16: 00234 (reinterpret_cast<int16_t *>(const_cast(tupleDatum.pData))) = 00235 boost::numeric_cast(value); 00236 break; 00237 case STANDARD_TYPE_INT_32: 00238 (reinterpret_cast<int32_t *>(const_cast(tupleDatum.pData))) = 00239 boost::numeric_cast(value); 00240 break; 00241 case STANDARD_TYPE_INT_64: 00242 (reinterpret_cast<int64_t *>(const_cast(tupleDatum.pData))) = 00243 boost::numeric_cast(value); 00244 break; 00245 default: 00246 throw InvalidValueException( 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(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("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(setIndex, regIndex, regType); 00379 break; 00380 case STANDARD_TYPE_UINT_8: 00381 regRef = new RegisterRef(setIndex, regIndex, regType); 00382 break; 00383 case STANDARD_TYPE_INT_16: 00384 regRef = new RegisterRef(setIndex, regIndex, regType); 00385 break; 00386 case STANDARD_TYPE_UINT_16: 00387 regRef = new RegisterRef(setIndex, regIndex, regType); 00388 break; 00389 case STANDARD_TYPE_INT_32: 00390 regRef = new RegisterRef(setIndex, regIndex, regType); 00391 break; 00392 case STANDARD_TYPE_UINT_32: 00393 regRef = new RegisterRef(setIndex, regIndex, regType); 00394 break; 00395 case STANDARD_TYPE_INT_64: 00396 regRef = new RegisterRef(setIndex, regIndex, regType); 00397 break; 00398 case STANDARD_TYPE_UINT_64: 00399 regRef = new RegisterRef(setIndex, regIndex, regType); 00400 break; 00401 case STANDARD_TYPE_REAL: 00402 regRef = new RegisterRef(setIndex, regIndex, regType); 00403 break; 00404 case STANDARD_TYPE_DOUBLE: 00405 regRef = new RegisterRef(setIndex, regIndex, regType); 00406 break; 00407 case STANDARD_TYPE_BOOL: 00408 regRef = new RegisterRef(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