00001 #include "xi-Message.h"
00002
00003 #include <vector>
00004
00005 namespace xi {
00006
00007 static const char* CIMsgClassAnsi =
00008 "{\n"
00009 " public:\n"
00010 " static int __idx;\n"
00011 " void* operator new(size_t, void*p) { return p; }\n"
00012 " void* operator new(size_t);\n"
00013 " void* operator new(size_t, int*, const int);\n"
00014 " void* operator new(size_t, int*, const int, const GroupDepNum);\n"
00015 " void* operator new(size_t, int*);\n"
00016 "#if CMK_MULTIPLE_DELETE\n"
00017 " void operator delete(void*p, void*){dealloc(p);}\n"
00018 " void operator delete(void*p){dealloc(p);}\n"
00019 " void operator delete(void*p, int*, const int){dealloc(p);}\n"
00020 " void operator delete(void*p, int*, const int, const GroupDepNum){dealloc(p);}\n"
00021 " void operator delete(void*p, int*){dealloc(p);}\n"
00022 "#endif\n"
00023 " void operator delete(void*p, size_t){dealloc(p);}\n"
00024 " static void* alloc(int,size_t, int*, int, GroupDepNum);\n"
00025 " static void dealloc(void *p);\n";
00026
00027 Message::Message(int l, NamedType* t, MsgVarList* mv) : type(t), mvlist(mv) {
00028 line = l;
00029 setTemplate(0);
00030 }
00031
00032 const char* Message::proxyPrefix(void) { return Prefix::Message; }
00033
00034 void Message::genAllocDecl(XStr& str) {
00035 int i, num;
00036 XStr mtype;
00037 mtype << type;
00038 if (templat) templat->genVars(mtype);
00039 str << CIMsgClassAnsi;
00040 str << " CMessage_" << mtype << "();\n";
00041 str << " static void *pack(" << mtype << " *p);\n";
00042 str << " static " << mtype << "* unpack(void* p);\n";
00043 num = numArrays();
00044 if (num > 0) {
00045 str << " void *operator new(size_t";
00046 for (i = 0; i < num; i++) str << ", int";
00047 str << ");\n";
00048 }
00049 str << " void *operator new(size_t, ";
00050 for (i = 0; i < num; i++) str << "int, ";
00051 str << "const int);\n";
00052 str << " void *operator new(size_t, ";
00053 for(i=0;i<num;i++)
00054 str << "int, ";
00055 str << "const int, const GroupDepNum);\n";
00056 str << "#if CMK_MULTIPLE_DELETE\n";
00057 if (num > 0) {
00058 str << " void operator delete(void *p";
00059 for (i = 0; i < num; i++) str << ", int";
00060 str << "){dealloc(p);}\n";
00061 }
00062 str << " void operator delete(void *p, ";
00063 for (i = 0; i < num; i++) str << "int, ";
00064 str << "const int){dealloc(p);}\n";
00065 str << " void operator delete(void *p, ";
00066 for (i = 0; i < num; i++) str << "int, ";
00067 str << "const int, const GroupDepNum){dealloc(p);}\n";
00068 str << "#endif\n";
00069 }
00070
00071 const char GroupDepNumStruct[] =
00072 "#ifndef GROUPDEPNUM_DECLARED\n"
00073 "# define GROUPDEPNUM_DECLARED\n"
00074 "struct GroupDepNum\n"
00075 "{\n"
00076 " int groupDepNum;\n"
00077 " explicit GroupDepNum(int g = 0) : groupDepNum{g} { }\n"
00078 " operator int() const { return groupDepNum; }\n"
00079 "};\n"
00080 "#endif\n";
00081
00082 void Message::genDecls(XStr& str) {
00083 XStr ptype;
00084 ptype << proxyPrefix() << type;
00085 if (type->isTemplated()) return;
00086 str << GroupDepNumStruct;
00087 str << "/* DECLS: ";
00088 print(str);
00089 str << " */\n";
00090 if (templat) templat->genSpec(str);
00091 str << "class ";
00092 type->print(str);
00093 str << ";\n";
00094 if (templat) templat->genSpec(str);
00095 str << "class " << ptype;
00096 if (external || type->isTemplated()) {
00097 str << ";\n";
00098 return;
00099 }
00100 str << ":public CkMessage";
00101
00102 genAllocDecl(str);
00103
00104 if (!(external || type->isTemplated())) {
00105
00106 str << " static void __register(const char *s, size_t size, CkPackFnPtr pack, "
00107 "CkUnpackFnPtr unpack) {\n";
00108 str << " __idx = CkRegisterMsg(s, pack, unpack, dealloc, size);\n";
00109 str << " }\n";
00110 }
00111 str << "};\n";
00112
00113 if (strncmp(type->getBaseName(), "MarshallMsg_", 12) == 0) {
00114 MsgVarList* ml;
00115 MsgVar* mv;
00116 int i;
00117 str << "class " << type << " : public " << ptype << " {\n";
00118 str << " public:\n";
00119 int num = numVars();
00120 for (i = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00121 mv = ml->msg_var;
00122 if (mv->isConditional() || mv->isArray()) {
00123 str << " /* ";
00124 mv->print(str);
00125 str << " */\n";
00126 str << " " << mv->type << " *" << mv->name << ";\n";
00127 }
00128 }
00129 str << "};\n";
00130 }
00131 }
00132
00133 void Message::genDefs(XStr& str) {
00134 int i, count, num = numVars();
00135 int numArray = numArrays();
00136 MsgVarList* ml;
00137 MsgVar* mv;
00138 XStr ptype, mtype, tspec;
00139 ptype << proxyPrefix() << type;
00140 if (templat) templat->genVars(ptype);
00141 mtype << type;
00142 if (templat) templat->genVars(mtype);
00143 if (templat) {
00144 templat->genSpec(tspec);
00145 tspec << " ";
00146 }
00147
00148 str << "/* DEFS: ";
00149 print(str);
00150 str << " */\n";
00151
00152 templateGuardBegin(templat, str);
00153 if (!(external || type->isTemplated())) {
00154
00155 str << tspec << "void *" << ptype << "::operator new(size_t s){\n";
00156 str << " return " << mtype << "::alloc(__idx, s, 0, 0, GroupDepNum{});\n}\n";
00157
00158 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz){\n";
00159 str << " return " << mtype << "::alloc(__idx, s, sz, 0, GroupDepNum{});\n}\n";
00160
00161 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,";
00162 str << "const int pb){\n";
00163 str << " return " << mtype << "::alloc(__idx, s, sz, pb, GroupDepNum{});\n}\n";
00164
00165 str << tspec << "void *" << ptype << "::operator new(size_t s, int* sz,";
00166 str << "const int pb, const GroupDepNum groupDepNum){\n";
00167 str << " return " << mtype << "::alloc(__idx, s, sz, pb, groupDepNum);\n}\n";
00168
00169 if (numArray > 0) {
00170 str << tspec << "void *" << ptype << "::operator new(size_t s";
00171 for (i = 0; i < numArray; i++) str << ", int sz" << i;
00172 str << ") {\n";
00173 str << " int sizes[" << numArray << "];\n";
00174 for (i = 0; i < numArray; i++) str << " sizes[" << i << "] = sz" << i << ";\n";
00175 str << " return " << mtype << "::alloc(__idx, s, sizes, 0, GroupDepNum{});\n";
00176 str << "}\n";
00177 }
00178
00179
00180 std::vector<MsgVar*> arrayVars;
00181 str << tspec << "void *" << ptype << "::operator new(size_t s, ";
00182 for (i = 0; i < numArray; i++) str << "int sz" << i << ", ";
00183 str << "const int p) {\n";
00184 if (numArray > 0) {
00185 str << " int sizes[" << numArray << "];\n";
00186 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00187 mv = ml->msg_var;
00188 if (mv->isArray()) {
00189 str << " sizes[" << count << "] = sz" << count << ";\n";
00190 count++;
00191 arrayVars.push_back(mv);
00192 }
00193 }
00194 }
00195 str << " return " << mtype << "::alloc(__idx, s, " << (numArray > 0 ? "sizes" : "0")
00196 << ", p, GroupDepNum{});\n";
00197 str << "}\n";
00198
00199
00200 arrayVars.clear();
00201 str << tspec << "void *"<< ptype << "::operator new(size_t s, ";
00202 for(i=0;i<numArray;i++)
00203 str << "int sz" << i << ", ";
00204 str << "const int p, const GroupDepNum groupDepNum) {\n";
00205 if (numArray>0) {
00206 str << " int sizes[" << numArray << "];\n";
00207 for(i=0, count=0, ml=mvlist ;i<num; i++, ml=ml->next) {
00208 mv = ml->msg_var;
00209 if (mv->isArray()) {
00210 str << " sizes[" << count << "] = sz" << count << ";\n";
00211 count ++;
00212 arrayVars.push_back(mv);
00213 }
00214 }
00215 }
00216 str << " return " << mtype << "::alloc(__idx, s, " << (numArray>0?"sizes":"0") << ", p, groupDepNum);\n";
00217 str << "}\n";
00218
00219
00220 str << tspec << "void* " << ptype;
00221 str << "::alloc(int msgnum, size_t sz, int *sizes, int pb, GroupDepNum groupDepNum) {\n";
00222 str << " CkpvAccess(_offsets)[0] = ALIGN_DEFAULT(sz);\n";
00223 for (count = 0; count < numArray; count++) {
00224 mv = arrayVars[count];
00225 str << " if(sizes==0)\n";
00226 str << " CkpvAccess(_offsets)[" << count + 1 << "] = CkpvAccess(_offsets)[0];\n";
00227 str << " else\n";
00228 str << " CkpvAccess(_offsets)[" << count + 1 << "] = CkpvAccess(_offsets)["
00229 << count << "] + ";
00230 str << "ALIGN_DEFAULT(sizeof(" << mv->type << ")*sizes[" << count << "]);\n";
00231 }
00232 str << " return CkAllocMsg(msgnum, CkpvAccess(_offsets)[" << numArray << "], pb, groupDepNum);\n";
00233 str << "}\n";
00234
00235 str << tspec << ptype << "::" << proxyPrefix() << type << "() {\n";
00236 str << mtype << " *newmsg = (" << mtype << " *)this;\n";
00237 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00238 mv = ml->msg_var;
00239 if (mv->isArray()) {
00240 str << " newmsg->" << mv->name << " = (" << mv->type << " *) ";
00241 str << "((char *)newmsg + CkpvAccess(_offsets)[" << count << "]);\n";
00242 count++;
00243 }
00244 }
00245 str << "}\n";
00246
00247 int numCond = numConditional();
00248 str << tspec << "void " << ptype << "::dealloc(void *p) {\n";
00249 if (numCond > 0) {
00250 str << " " << mtype << " *msg = (" << mtype << "*) p;\n";
00251 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00252 mv = ml->msg_var;
00253 if (mv->isConditional()) {
00254 if (mv->type->isPointer())
00255 XLAT_ERROR_NOCOL("conditional variable cannot be a pointer", line);
00256 str << " CkConditional *cond_" << mv->name
00257 << " = static_cast<CkConditional*>(msg->" << mv->name << ");\n";
00258 str << " if (cond_" << mv->name << "!=NULL) cond_" << mv->name
00259 << "->deallocate();\n";
00260 }
00261 }
00262 }
00263 str << " CkFreeMsg(p);\n";
00264 str << "}\n";
00265
00266 str << tspec << "void* " << ptype << "::pack(" << mtype << " *msg) {\n";
00267 for (i = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00268 mv = ml->msg_var;
00269 if (mv->isArray()) {
00270 str << " msg->" << mv->name << " = (" << mv->type << " *) ";
00271 str << "((char *)msg->" << mv->name << " - (char *)msg);\n";
00272 }
00273 }
00274 if (numCond > 0) {
00275 str << " int impl_off[" << numCond + 1 << "];\n";
00276 str << " impl_off[0] = UsrToEnv(msg)->getUsersize();\n";
00277 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00278 mv = ml->msg_var;
00279 if (mv->isConditional()) {
00280 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
00281 mv->type->print(str);
00282 str << " " << mv->name << " */\n";
00283 str << " PUP::sizer implP;\n";
00284 str << " implP|*msg->" << mv->name << ";\n";
00285 str << " impl_off[" << count + 1 << "] = impl_off[" << count
00286 << "] + implP.size();\n";
00287 str << " } else {\n";
00288 str << " impl_off[" << count + 1 << "] = impl_off[" << count << "];\n";
00289 str << " }\n";
00290 count++;
00291 }
00292 }
00293 str << " " << mtype << " *newmsg = (" << mtype << "*) CkAllocMsg(__idx, impl_off["
00294 << numCond << "], UsrToEnv(msg)->getPriobits());\n";
00295 str << " envelope *newenv = UsrToEnv(newmsg);\n";
00296 str << " UInt newSize = newenv->getTotalsize();\n";
00297 str << " CmiMemcpy(newenv, UsrToEnv(msg), impl_off[0]+sizeof(envelope));\n";
00298 str << " newenv->setTotalsize(newSize);\n";
00299 str << " if (UsrToEnv(msg)->getPriobits() > 0) CmiMemcpy(newenv->getPrioPtr(), "
00300 "UsrToEnv(msg)->getPrioPtr(), newenv->getPrioBytes());\n";
00301 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00302 mv = ml->msg_var;
00303 if (mv->isConditional()) {
00304 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
00305 mv->type->print(str);
00306 str << " " << mv->name << " */\n";
00307 str << " newmsg->" << mv->name << " = (";
00308 mv->type->print(str);
00309 str << "*)(((char*)newmsg)+impl_off[" << count << "]);\n";
00310 str << " PUP::toMem implP((void *)newmsg->" << mv->name << ");\n";
00311 str << " implP|*msg->" << mv->name << ";\n";
00312 str << " newmsg->" << mv->name << " = (" << mv->type
00313 << "*) ((char *)newmsg->" << mv->name << " - (char *)newmsg);\n";
00314 str << " }\n";
00315 count++;
00316 }
00317 }
00318 str << " CkFreeMsg(msg);\n";
00319 str << " msg = newmsg;\n";
00320 }
00321 str << " return (void *) msg;\n}\n";
00322
00323 str << tspec << mtype << "* " << ptype << "::unpack(void* buf) {\n";
00324 str << " " << mtype << " *msg = (" << mtype << " *) buf;\n";
00325 for (i = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00326 mv = ml->msg_var;
00327 if (mv->isArray()) {
00328 str << " msg->" << mv->name << " = (" << mv->type << " *) ";
00329 str << "((size_t)msg->" << mv->name << " + (char *)msg);\n";
00330 }
00331 }
00332 if (numCond > 0) {
00333 for (i = 0, count = 0, ml = mvlist; i < num; i++, ml = ml->next) {
00334 mv = ml->msg_var;
00335 if (mv->isConditional()) {
00336 str << " if (msg->" << mv->name << "!=NULL) { /* conditional packing of ";
00337 mv->type->print(str);
00338 str << " " << mv->name << " */\n";
00339 str << " PUP::fromMem implP((char*)msg + (size_t)msg->" << mv->name
00340 << ");\n";
00341 str << " msg->" << mv->name << " = new " << mv->type << ";\n";
00342 str << " implP|*msg->" << mv->name << ";\n";
00343 str << " }\n";
00344 count++;
00345 }
00346 }
00347 }
00348 str << " return msg;\n}\n";
00349 }
00350 if (!templat) {
00351 if (!external && !type->isTemplated()) {
00352 str << "int " << ptype << "::__idx=0;\n";
00353 }
00354 } else {
00355 str << tspec << "int " << ptype << "::__idx=0;\n";
00356 }
00357 templateGuardEnd(str);
00358 }
00359
00360 void Message::genReg(XStr& str) {
00361 str << "/* REG: ";
00362 print(str);
00363 str << "*/\n";
00364 if (!templat && !external) {
00365 XStr ptype, mtype, tspec;
00366 ptype << proxyPrefix() << type;
00367 str << ptype << "::__register(\"" << type << "\", sizeof(" << type << "),";
00368 str << "(CkPackFnPtr) " << type << "::pack,";
00369 str << "(CkUnpackFnPtr) " << type << "::unpack);\n";
00370 }
00371 }
00372
00373 void Message::print(XStr& str) {
00374 if (external) str << "extern ";
00375 if (templat) templat->genSpec(str);
00376 str << "message ";
00377 type->print(str);
00378 printVars(str);
00379 str << ";\n";
00380 }
00381
00382 void Message::printVars(XStr& str) {
00383 if (mvlist != 0) {
00384 str << "{\n";
00385 mvlist->print(str);
00386 str << "}\n";
00387 }
00388 }
00389
00390 int Message::numArrays(void) {
00391 if (mvlist == 0) return 0;
00392 int count = 0;
00393 MsgVarList* mv = mvlist;
00394 for (int i = 0; i < mvlist->len(); ++i, mv = mv->next)
00395 if (mv->msg_var->isArray()) count++;
00396 return count;
00397 }
00398
00399 int Message::numConditional(void) {
00400 if (mvlist == 0) return 0;
00401 int count = 0;
00402 MsgVarList* mv = mvlist;
00403 for (int i = 0; i < mvlist->len(); ++i, mv = mv->next)
00404 if (mv->msg_var->isConditional()) count++;
00405 return count;
00406 }
00407
00408 int Message::numVars(void) { return ((mvlist == 0) ? 0 : mvlist->len()); }
00409
00410 MsgVar::MsgVar(Type* t, const char* n, int c, int a)
00411 : type(t), name(n), cond(c), array(a) {}
00412
00413 Type* MsgVar::getType() { return type; }
00414
00415 const char* MsgVar::getName() { return name; }
00416
00417 int MsgVar::isConditional() { return cond; }
00418
00419 int MsgVar::isArray() { return array; }
00420
00421 void MsgVar::print(XStr& str) {
00422 str << (isConditional() ? "conditional " : "");
00423 type->print(str);
00424 str << " " << name << (isArray() ? "[]" : "") << ";";
00425 }
00426
00427 MsgVarList::MsgVarList(MsgVar* mv, MsgVarList* n) : msg_var(mv), next(n) {}
00428
00429 void MsgVarList::print(XStr& str) {
00430 msg_var->print(str);
00431 str << "\n";
00432 if (next) next->print(str);
00433 }
00434
00435 int MsgVarList::len(void) { return (next == 0) ? 1 : (next->len() + 1); }
00436
00437 }