ExtendedInstruction.h

Go to the documentation of this file.
00001 /*
00002 // $Id: //open/dev/fennel/calculator/ExtendedInstruction.h#5 $
00003 // Fennel is a library of data storage and processing components.
00004 // Copyright (C) 2005-2009 The Eigenbase Project
00005 // Copyright (C) 2004-2009 SQLstream, Inc.
00006 // Copyright (C) 2009-2009 LucidEra, Inc.
00007 //
00008 // This program is free software; you can redistribute it and/or modify it
00009 // under the terms of the GNU General Public License as published by the Free
00010 // Software Foundation; either version 2 of the License, or (at your option)
00011 // any later version approved by The Eigenbase Project.
00012 //
00013 // This program is distributed in the hope that it will be useful,
00014 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00015 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016 // GNU General Public License for more details.
00017 //
00018 // You should have received a copy of the GNU General Public License
00019 // along with this program; if not, write to the Free Software
00020 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021 */
00022 
00023 #ifndef Fennel_ExtendedInstruction_Included
00024 #define Fennel_ExtendedInstruction_Included
00025 
00026 #include "fennel/calculator/Instruction.h"
00027 #include "fennel/calculator/Calculator.h"
00028 #include "fennel/calculator/ExtendedInstructionContext.h"
00029 
00030 #include <boost/scoped_ptr.hpp>
00031 
00032 FENNEL_BEGIN_NAMESPACE
00033 
00034 using std::string;
00035 class Register;
00036 class ExtendedInstruction;
00037 
00038 
00044 class FENNEL_CALCULATOR_EXPORT ExtendedInstructionDef
00045 {
00046 protected:
00047     string _name;
00048     vector<StandardTypeDescriptorOrdinal> _parameterTypes;
00049     string _signature;
00050 
00051     friend class ExtendedInstructionTable;
00052 
00056     explicit
00057     ExtendedInstructionDef(
00058         string const &name,
00059         vector<StandardTypeDescriptorOrdinal> const &parameterTypes)
00060         : _name(name),
00061           _parameterTypes(parameterTypes),
00062           _signature(computeSignature())
00063     {
00064     }
00065 public:
00066     virtual
00067     ~ExtendedInstructionDef() {}
00068 
00072     string getName()
00073     {
00074         return _name;
00075     }
00076 
00080     const vector<StandardTypeDescriptorOrdinal> &getParameterTypes()
00081     {
00082         return _parameterTypes;
00083     }
00091     string getSignature() const
00092     {
00093         return _signature;
00094     }
00095 
00101     virtual ExtendedInstruction *createInstruction(
00102         vector<RegisterReference *> const &regs) = 0;
00103 
00104 private:
00105     string computeSignature();
00106 };
00107 
00114 template <typename T>
00115 class FunctorExtendedInstructionDef : public ExtendedInstructionDef
00116 {
00117     friend class ExtendedInstructionTable;
00118 
00119 protected:
00124     explicit
00125     FunctorExtendedInstructionDef(
00126         string const &name,
00127         vector<StandardTypeDescriptorOrdinal> const &parameterTypes,
00128         typename T::Functor functor)
00129         : ExtendedInstructionDef(name, parameterTypes),
00130           _functor(functor)
00131     {
00132         assert(functor != NULL);
00133     }
00134 public:
00135     typename T::Functor _functor;
00136 
00137     // implement ExtendedInstructionDef
00138     ExtendedInstruction *createInstruction(
00139         vector<RegisterReference *> const &regs)
00140     {
00141         return T::create(*this,regs);
00142     }
00143 };
00144 
00145 
00146 
00156 class FENNEL_CALCULATOR_EXPORT ExtendedInstruction
00157     : public Instruction
00158 {
00159 protected:
00160     virtual ExtendedInstructionDef const &getDef() const = 0;
00161 
00162     template <typename T>
00163     static void describeArg(
00164         string &out,
00165         bool values,
00166         RegisterRef<T> * const reg)
00167     {
00168         out += reg->toString();
00169         if (values) {
00170             out += " ( ";
00171             if (reg->isNull()) {
00172                 out += "NULL";
00173             } else {
00174                 out += reg->valueToString();
00175             }
00176             out += " ) ";
00177         }
00178     }
00179 
00180 public:
00181     explicit
00182     ExtendedInstruction()
00183     {}
00184 
00185     // implement Instruction
00186     const char *longName() const
00187     {
00188         return const_cast<ExtendedInstructionDef &>(getDef()).getName().c_str();
00189     }
00190 
00191     const char *shortName() const
00192     {
00193         return const_cast<ExtendedInstructionDef &>(getDef()).getName().c_str();
00194     }
00195 };
00196 
00202 class FENNEL_CALCULATOR_EXPORT ExtendedInstruction0
00203     : public ExtendedInstruction
00204 {
00205 public:
00211     typedef void (*Functor)();
00215     typedef FunctorExtendedInstructionDef<ExtendedInstruction0> DefT;
00216 
00217 protected:
00218     DefT _def;
00219 
00220     // implement ExtendedInstruction
00221     ExtendedInstructionDef const &getDef() const
00222     {
00223         return static_cast<ExtendedInstructionDef const &>(_def);
00224     }
00225 
00226 public:
00227     explicit
00228     ExtendedInstruction0(DefT &def)
00229         : ExtendedInstruction(),
00230           _def(def)
00231     {}
00232 
00233     static ExtendedInstruction0 *create(
00234         DefT &def,
00235         vector<RegisterReference *> const &regRefs)
00236     {
00237         assert(regRefs.size() == 0);
00238         return new ExtendedInstruction0(def);
00239     }
00240 
00241     // implement Instruction
00242     void describe(string& out, bool values) const
00243     {
00244         out = "CALL '";
00245         out += _def.getSignature();
00246         out += "'";
00247     }
00248     void exec(TProgramCounter &pc) const
00249     {
00250         pc++;
00251         try {
00252             (*_def._functor)();
00253         } catch (char const * str) {
00254             throw CalcMessage(str, pc - 1);
00255         }
00256     }
00257 };
00258 
00264 class FENNEL_CALCULATOR_EXPORT ExtendedInstruction0Context
00265     : public ExtendedInstruction
00266 {
00267 public:
00273     typedef void (*Functor)(boost::scoped_ptr<ExtendedInstructionContext>& ctx);
00277     typedef FunctorExtendedInstructionDef<ExtendedInstruction0Context> DefT;
00278 
00279 protected:
00280     DefT _def;
00281     boost::scoped_ptr<ExtendedInstructionContext> _ctx;
00282 
00283     // implement ExtendedInstruction
00284     ExtendedInstructionDef const &getDef() const
00285     {
00286         return static_cast<ExtendedInstructionDef const &>(_def);
00287     }
00288 
00289 public:
00290     explicit
00291     ExtendedInstruction0Context(DefT &def)
00292         : ExtendedInstruction(),
00293           _def(def),
00294           _ctx(0)
00295     {}
00296 
00297     static ExtendedInstruction0Context *create(
00298         DefT &def,
00299         vector<RegisterReference *> const &regRefs)
00300     {
00301         assert(regRefs.size() == 0);
00302         return new ExtendedInstruction0Context(def);
00303     }
00304 
00305     // implement Instruction
00306     void describe(string& out, bool values) const
00307     {
00308         out = "CALL '";
00309         out += _def.getSignature();
00310         out += "'";
00311     }
00312     void exec(TProgramCounter &pc) const
00313     {
00314         pc++;
00315         try {
00316             // TODO: Remove this const cast. Ugly, but exec is defined as const
00317             // TODO: in virtual above.
00318             (*_def._functor)(
00319                 const_cast<boost::scoped_ptr<ExtendedInstructionContext>& >(
00320                     _ctx));
00321         } catch (char const * str) {
00322             throw CalcMessage(str, pc - 1);
00323         }
00324     }
00325 };
00326 
00331 template <typename T0>
00332 class ExtendedInstruction1 : public ExtendedInstruction
00333 {
00334 public:
00341     typedef void (*Functor)(RegisterRef<T0>* reg0);
00345     typedef FunctorExtendedInstructionDef<ExtendedInstruction1<T0> > DefT;
00346 
00347 private:
00348     DefT _def;
00349     RegisterRef<T0>* _reg0;
00350 
00351 protected:
00352     // implement ExtendedInstruction
00353     ExtendedInstructionDef const &getDef() const
00354     {
00355         return _def;
00356     }
00357 
00358 public:
00359     explicit
00360     ExtendedInstruction1(
00361         DefT &def,
00362         RegisterRef<T0>* const reg0)
00363         : _def(def),
00364           _reg0(reg0)
00365     {}
00366 
00367     static ExtendedInstruction1<T0> *create(
00368         DefT &def,
00369         vector<RegisterReference *> const &regRefs)
00370     {
00371         assert(regRefs.size() == 1);
00372         // todo:        assert(regRefs[0].getType() == T0::typeCode);
00373         return new ExtendedInstruction1<T0>(
00374             def,
00375             static_cast<RegisterRef<T0> *>(regRefs[0]));
00376     }
00377 
00378     // implement Instruction
00379     void describe(string& out, bool values) const
00380     {
00381         out = "CALL '";
00382         out += _def.getSignature();
00383         out += "' ";
00384         describeArg(out, values, _reg0);
00385     }
00386     void exec(TProgramCounter &pc) const
00387     {
00388         pc++;
00389         try {
00390             (*_def._functor)(_reg0);
00391         } catch (char const * str) {
00392             throw CalcMessage(str, pc - 1);
00393         }
00394     }
00395 };
00396 
00401 template <typename T0>
00402 class ExtendedInstruction1Context : public ExtendedInstruction
00403 {
00404 public:
00411     typedef void (*Functor)(
00412         boost::scoped_ptr<ExtendedInstructionContext>& ctx,
00413         RegisterRef<T0>* reg0);
00414 
00418     typedef FunctorExtendedInstructionDef<ExtendedInstruction1Context<T0> >
00419         DefT;
00420 
00421 private:
00422     DefT _def;
00423     boost::scoped_ptr<ExtendedInstructionContext> _ctx;
00424     RegisterRef<T0>* _reg0;
00425 
00426 protected:
00427     // implement ExtendedInstruction
00428     ExtendedInstructionDef const &getDef() const
00429     {
00430         return _def;
00431     }
00432 
00433 public:
00434     explicit
00435     ExtendedInstruction1Context(
00436         DefT &def,
00437         RegisterRef<T0>* const reg0)
00438         : _def(def),
00439           _ctx(0),
00440           _reg0(reg0)
00441     {}
00442 
00443     static ExtendedInstruction1Context<T0> *create(
00444         DefT &def,
00445         vector<RegisterReference *> const &regRefs)
00446     {
00447         assert(regRefs.size() == 1);
00448         // todo:        assert(regRefs[0].getType() == T0::typeCode);
00449         return new ExtendedInstruction1Context<T0>(
00450             def,
00451             static_cast<RegisterRef<T0> *>(regRefs[0]));
00452     }
00453 
00454     // implement Instruction
00455     void describe(string& out, bool values) const
00456     {
00457         out = "CALL '";
00458         out += _def.getSignature();
00459         out += "' ";
00460         describeArg(out, values, _reg0);
00461     }
00462     void exec(TProgramCounter &pc) const
00463     {
00464         pc++;
00465         try {
00466             // TODO: Remove this const cast. Ugly, but exec is defined as const
00467             // TODO: in virtual above.
00468             (*_def._functor)(
00469                 const_cast<boost::scoped_ptr<ExtendedInstructionContext>& >(
00470                     _ctx),
00471                 _reg0);
00472         } catch (char const * str) {
00473             throw CalcMessage(str, pc - 1);
00474         }
00475     }
00476 };
00477 
00482 template <typename T0, typename T1>
00483 class ExtendedInstruction2 : public ExtendedInstruction
00484 {
00485 public:
00496     typedef void (*Functor)(
00497         RegisterRef<T0>* const reg0,
00498         RegisterRef<T1>* const reg1);
00502     typedef FunctorExtendedInstructionDef<ExtendedInstruction2<T0,T1> > DefT;
00503 
00504 private:
00505     DefT _def;
00506     RegisterRef<T0>* _reg0;
00507     RegisterRef<T1>* _reg1;
00508 
00509 protected:
00510     // implement ExtendedInstruction
00511     ExtendedInstructionDef const &getDef() const
00512     {
00513         return _def;
00514     }
00515 
00516 public:
00517     explicit
00518     ExtendedInstruction2(
00519         DefT &def,
00520         RegisterRef<T0>* const reg0,
00521         RegisterRef<T1>* const reg1)
00522         : _def(def),
00523           _reg0(reg0),
00524           _reg1(reg1)
00525     {}
00526 
00527     static ExtendedInstruction2<T0,T1> *create(
00528         DefT &def,
00529         vector<RegisterReference *> const &regRefs)
00530     {
00531         assert(regRefs.size() == 2);
00532         return new ExtendedInstruction2<T0,T1>(
00533             def,
00534             static_cast<RegisterRef<T0> *>(regRefs[0]),
00535             static_cast<RegisterRef<T1> *>(regRefs[1]));
00536     }
00537 
00538     // implement Instruction
00539     void describe(string& out, bool values) const
00540     {
00541         out = "CALL '";
00542         out += _def.getSignature();
00543         out += "' ";
00544         describeArg(out, values, _reg0);
00545         out += ", ";
00546         describeArg(out, values, _reg1);
00547     }
00548     void exec(TProgramCounter &pc) const
00549     {
00550         pc++;
00551         try {
00552             (*_def._functor)(_reg0,_reg1);
00553         } catch (char const * str) {
00554             throw CalcMessage(str, pc - 1);
00555         }
00556     }
00557 };
00558 
00563 template <typename T0, typename T1>
00564 class ExtendedInstruction2Context : public ExtendedInstruction
00565 {
00566 public:
00577     typedef void (*Functor)(
00578         boost::scoped_ptr<ExtendedInstructionContext>& ctx,
00579         RegisterRef<T0>* const reg0,
00580         RegisterRef<T1>* const reg1);
00581 
00585     typedef FunctorExtendedInstructionDef<ExtendedInstruction2Context<T0,T1> >
00586         DefT;
00587 
00588 private:
00589     DefT _def;
00590     boost::scoped_ptr<ExtendedInstructionContext> _ctx;
00591     RegisterRef<T0>* _reg0;
00592     RegisterRef<T1>* _reg1;
00593 
00594 protected:
00595     // implement ExtendedInstruction
00596     ExtendedInstructionDef const &getDef() const
00597     {
00598         return _def;
00599     }
00600 
00601 public:
00602     explicit
00603     ExtendedInstruction2Context(
00604         DefT &def,
00605         RegisterRef<T0>* const reg0,
00606         RegisterRef<T1>* const reg1)
00607         : _def(def),
00608           _ctx(0),
00609           _reg0(reg0),
00610           _reg1(reg1)
00611     {}
00612 
00613     static ExtendedInstruction2Context<T0,T1> *create(
00614         DefT &def,
00615         vector<RegisterReference *> const &regRefs)
00616     {
00617         assert(regRefs.size() == 2);
00618         return new ExtendedInstruction2Context<T0,T1>(
00619             def,
00620             static_cast<RegisterRef<T0> *>(regRefs[0]),
00621             static_cast<RegisterRef<T1> *>(regRefs[1]));
00622     }
00623 
00624     // implement Instruction
00625     void describe(string& out, bool values) const
00626     {
00627         out = "CALL '";
00628         out += _def.getSignature();
00629         out += "' ";
00630         describeArg(out, values, _reg0);
00631         out += ", ";
00632         describeArg(out, values, _reg1);
00633     }
00634     void exec(TProgramCounter &pc) const
00635     {
00636         pc++;
00637         try {
00638             // TODO: Remove this const cast. Ugly, but exec is defined as const
00639             // TODO: in virtual above.
00640             (*_def._functor)(
00641                 const_cast<boost::scoped_ptr<ExtendedInstructionContext>& >(
00642                     _ctx),
00643                 _reg0,
00644                 _reg1);
00645         } catch (char const * str) {
00646             throw CalcMessage(str, pc - 1);
00647         }
00648     }
00649 };
00650 
00655 template <typename T0, typename T1, typename T2>
00656 class ExtendedInstruction3 : public ExtendedInstruction
00657 {
00658 public:
00669     typedef void (*Functor)(
00670         RegisterRef<T0>* const reg0,
00671         RegisterRef<T1>* const reg1,
00672         RegisterRef<T2>* const reg2);
00676     typedef FunctorExtendedInstructionDef<ExtendedInstruction3<T0,T1,T2> > DefT;
00677 
00678 private:
00679     DefT _def;
00680     RegisterRef<T0>* _reg0;
00681     RegisterRef<T1>* _reg1;
00682     RegisterRef<T2>* _reg2;
00683 
00684 protected:
00685     // implement ExtendedInstruction
00686     ExtendedInstructionDef const &getDef() const
00687     {
00688         return _def;
00689     }
00690 
00691 public:
00692     explicit
00693     ExtendedInstruction3(
00694         DefT &def,
00695         RegisterRef<T0>* const reg0,
00696         RegisterRef<T1>* const reg1,
00697         RegisterRef<T2>* const reg2)
00698         : _def(def),
00699           _reg0(reg0),
00700           _reg1(reg1),
00701           _reg2(reg2)
00702     {}
00703 
00704     static ExtendedInstruction3<T0,T1,T2> *create(
00705         DefT &def,
00706         vector<RegisterReference *> const &regRefs)
00707     {
00708         assert(regRefs.size() == 3);
00709         return new ExtendedInstruction3<T0,T1,T2>(
00710             def,
00711             static_cast<RegisterRef<T0> *>(regRefs[0]),
00712             static_cast<RegisterRef<T1> *>(regRefs[1]),
00713             static_cast<RegisterRef<T2> *>(regRefs[2]));
00714     }
00715 
00716     // implement Instruction
00717     void describe(string& out, bool values) const
00718     {
00719         out = "CALL '";
00720         out += _def.getSignature();
00721         out += "' ";
00722         describeArg(out, values, _reg0);
00723         out += ", ";
00724         describeArg(out, values, _reg1);
00725         out += ", ";
00726         describeArg(out, values, _reg2);
00727     }
00728     void exec(TProgramCounter &pc) const
00729     {
00730         pc++;
00731         try {
00732             (*_def._functor)(_reg0,_reg1,_reg2);
00733         } catch (char const * str) {
00734             throw CalcMessage(str, pc - 1);
00735         }
00736     }
00737 };
00738 
00743 template <typename T0, typename T1, typename T2>
00744 class ExtendedInstruction3Context : public ExtendedInstruction
00745 {
00746 public:
00758     typedef void (*Functor)(
00759         boost::scoped_ptr<ExtendedInstructionContext>& ctx,
00760         RegisterRef<T0>* const reg0,
00761         RegisterRef<T1>* const reg1,
00762         RegisterRef<T2>* const reg2);
00766     typedef
00767         FunctorExtendedInstructionDef<ExtendedInstruction3Context<T0,T1,T2> >
00768         DefT;
00769 
00770 private:
00771     DefT _def;
00772     boost::scoped_ptr<ExtendedInstructionContext> _ctx;
00773     RegisterRef<T0>* _reg0;
00774     RegisterRef<T1>* _reg1;
00775     RegisterRef<T2>* _reg2;
00776 
00777 protected:
00778     // implement ExtendedInstruction
00779     ExtendedInstructionDef const &getDef() const
00780     {
00781         return _def;
00782     }
00783 
00784 public:
00785     explicit
00786     ExtendedInstruction3Context(
00787         DefT &def,
00788         RegisterRef<T0>* const reg0,
00789         RegisterRef<T1>* const reg1,
00790         RegisterRef<T2>* const reg2)
00791         : _def(def),
00792           _ctx(0),
00793           _reg0(reg0),
00794           _reg1(reg1),
00795           _reg2(reg2)
00796     {}
00797 
00798     static ExtendedInstruction3Context<T0,T1,T2> *create(
00799         DefT &def,
00800         vector<RegisterReference *> const &regRefs)
00801     {
00802         assert(regRefs.size() == 3);
00803         return new ExtendedInstruction3Context<T0,T1,T2>(
00804             def,
00805             static_cast<RegisterRef<T0> *>(regRefs[0]),
00806             static_cast<RegisterRef<T1> *>(regRefs[1]),
00807             static_cast<RegisterRef<T2> *>(regRefs[2]));
00808     }
00809 
00810     // implement Instruction
00811     void describe(string& out, bool values) const
00812     {
00813         out = "CALL '";
00814         out += _def.getSignature();
00815         out += "' ";
00816         describeArg(out, values, _reg0);
00817         out += ", ";
00818         describeArg(out, values, _reg1);
00819         out += ", ";
00820         describeArg(out, values, _reg2);
00821     }
00822     void exec(TProgramCounter &pc) const
00823     {
00824         pc++;
00825         try {
00826             // TODO: Remove this const cast. Ugly, but exec is defined as const
00827             // TODO: in virtual above.
00828             (*_def._functor)(
00829                 const_cast<boost::scoped_ptr<ExtendedInstructionContext>& >(
00830                     _ctx),
00831                 _reg0, _reg1, _reg2);
00832         } catch (char const * str) {
00833             throw CalcMessage(str, pc - 1);
00834         }
00835     }
00836 };
00837 
00842 template <typename T0, typename T1, typename T2, typename T3>
00843 class ExtendedInstruction4 : public ExtendedInstruction
00844 {
00845 public:
00857     typedef void (*Functor)(
00858         RegisterRef<T0>* const reg0,
00859         RegisterRef<T1>* const reg1,
00860         RegisterRef<T2>* const reg2,
00861         RegisterRef<T3>* const reg3);
00865     typedef FunctorExtendedInstructionDef<
00866         ExtendedInstruction4<T0,T1,T2,T3> > DefT;
00867 
00868 private:
00869     DefT _def;
00870     RegisterRef<T0>* _reg0;
00871     RegisterRef<T1>* _reg1;
00872     RegisterRef<T2>* _reg2;
00873     RegisterRef<T3>* _reg3;
00874 
00875 protected:
00876     // implement ExtendedInstruction
00877     ExtendedInstructionDef const &getDef() const
00878     {
00879         return _def;
00880     }
00881 
00882 public:
00883     explicit
00884     ExtendedInstruction4(
00885         DefT &def,
00886         RegisterRef<T0>* const reg0,
00887         RegisterRef<T1>* const reg1,
00888         RegisterRef<T2>* const reg2,
00889         RegisterRef<T3>* const reg3)
00890         : _def(def),
00891           _reg0(reg0),
00892           _reg1(reg1),
00893           _reg2(reg2),
00894           _reg3(reg3)
00895     {}
00896 
00897     static ExtendedInstruction4<T0,T1,T2,T3> *create(
00898         DefT &def,
00899         vector<RegisterReference *> const &regRefs)
00900     {
00901         assert(regRefs.size() == 4);
00902         return new ExtendedInstruction4<T0,T1,T2,T3>(
00903             def,
00904             static_cast<RegisterRef<T0> *>(regRefs[0]),
00905             static_cast<RegisterRef<T1> *>(regRefs[1]),
00906             static_cast<RegisterRef<T2> *>(regRefs[2]),
00907             static_cast<RegisterRef<T3> *>(regRefs[3]));
00908     }
00909 
00910     // implement Instruction
00911     void describe(string& out, bool values) const
00912     {
00913         out = "CALL '";
00914         out += _def.getSignature();
00915         out += "' ";
00916         describeArg(out, values, _reg0);
00917         out += ", ";
00918         describeArg(out, values, _reg1);
00919         out += ", ";
00920         describeArg(out, values, _reg2);
00921         out += ", ";
00922         describeArg(out, values, _reg3);
00923     }
00924     void exec(TProgramCounter &pc) const
00925     {
00926         pc++;
00927         try {
00928             (*_def._functor)(_reg0,_reg1,_reg2,_reg3);
00929         } catch (char const * str) {
00930             throw CalcMessage(str, pc - 1);
00931         }
00932     }
00933 };
00938 template <typename T0, typename T1, typename T2, typename T3>
00939 class ExtendedInstruction4Context : public ExtendedInstruction
00940 {
00941 public:
00953     typedef void (*Functor)(
00954         boost::scoped_ptr<ExtendedInstructionContext>& ctx,
00955         RegisterRef<T0>* const reg0,
00956         RegisterRef<T1>* const reg1,
00957         RegisterRef<T2>* const reg2,
00958         RegisterRef<T3>* const reg3);
00959 
00963     typedef FunctorExtendedInstructionDef<
00964         ExtendedInstruction4Context<T0,T1,T2,T3> > DefT;
00965 
00966 private:
00967     DefT _def;
00968     boost::scoped_ptr<ExtendedInstructionContext> _ctx;
00969     RegisterRef<T0>* _reg0;
00970     RegisterRef<T1>* _reg1;
00971     RegisterRef<T2>* _reg2;
00972     RegisterRef<T3>* _reg3;
00973 
00974 protected:
00975     // implement ExtendedInstruction
00976     ExtendedInstructionDef const &getDef() const
00977     {
00978         return _def;
00979     }
00980 
00981 public:
00982     explicit
00983     ExtendedInstruction4Context(
00984         DefT &def,
00985         RegisterRef<T0>* const reg0,
00986         RegisterRef<T1>* const reg1,
00987         RegisterRef<T2>* const reg2,
00988         RegisterRef<T3>* const reg3)
00989         : _def(def),
00990           _ctx(0),
00991           _reg0(reg0),
00992           _reg1(reg1),
00993           _reg2(reg2),
00994           _reg3(reg3)
00995     {}
00996 
00997     static ExtendedInstruction4Context<T0,T1,T2,T3> *create(
00998         DefT &def,
00999         vector<RegisterReference *> const &regRefs)
01000     {
01001         assert(regRefs.size() == 4);
01002         return new ExtendedInstruction4Context<T0,T1,T2,T3>(
01003             def,
01004             static_cast<RegisterRef<T0> *>(regRefs[0]),
01005             static_cast<RegisterRef<T1> *>(regRefs[1]),
01006             static_cast<RegisterRef<T2> *>(regRefs[2]),
01007             static_cast<RegisterRef<T3> *>(regRefs[3]));
01008     }
01009 
01010     // implement Instruction
01011     void describe(string& out, bool values) const
01012     {
01013         out = "CALL '";
01014         out += _def.getSignature();
01015         out += "' ";
01016         describeArg(out, values, _reg0);
01017         out += ", ";
01018         describeArg(out, values, _reg1);
01019         out += ", ";
01020         describeArg(out, values, _reg2);
01021         out += ", ";
01022         describeArg(out, values, _reg3);
01023     }
01024     void exec(TProgramCounter &pc) const
01025     {
01026         pc++;
01027         try {
01028             // TODO: Remove this const cast. Ugly, but exec is defined as const
01029             // TODO: in virtual above.
01030             (*_def._functor)(
01031                 const_cast<boost::scoped_ptr<ExtendedInstructionContext>& >(
01032                     _ctx),
01033                 _reg0, _reg1, _reg2, _reg3);
01034         } catch (char const * str) {
01035             throw CalcMessage(str, pc - 1);
01036         }
01037     }
01038 };
01039 
01044 template <typename T0, typename T1, typename T2, typename T3, typename T4>
01045 class ExtendedInstruction5 : public ExtendedInstruction
01046 {
01047 public:
01059     typedef void (*Functor)(
01060         RegisterRef<T0>* const reg0,
01061         RegisterRef<T1>* const reg1,
01062         RegisterRef<T2>* const reg2,
01063         RegisterRef<T3>* const reg3,
01064         RegisterRef<T4>* const reg4);
01065 
01069     typedef FunctorExtendedInstructionDef<
01070         ExtendedInstruction5<T0,T1,T2,T3,T4> > DefT;
01071 
01072 private:
01073     DefT _def;
01074     RegisterRef<T0>* _reg0;
01075     RegisterRef<T1>* _reg1;
01076     RegisterRef<T2>* _reg2;
01077     RegisterRef<T3>* _reg3;
01078     RegisterRef<T4>* _reg4;
01079 
01080 protected:
01081     // implement ExtendedInstruction
01082     ExtendedInstructionDef const &getDef() const
01083     {
01084         return _def;
01085     }
01086 
01087 public:
01088     explicit
01089     ExtendedInstruction5(
01090         DefT &def,
01091         RegisterRef<T0>* const reg0,
01092         RegisterRef<T1>* const reg1,
01093         RegisterRef<T2>* const reg2,
01094         RegisterRef<T3>* const reg3,
01095         RegisterRef<T4>* const reg4)
01096         : _def(def),
01097           _reg0(reg0),
01098           _reg1(reg1),
01099           _reg2(reg2),
01100           _reg3(reg3),
01101           _reg4(reg4)
01102     {}
01103 
01104     static ExtendedInstruction5<T0,T1,T2,T3,T4> *create(
01105         DefT &def,
01106         vector<RegisterReference *> const &regRefs)
01107     {
01108         assert(regRefs.size() == 5);
01109         return new ExtendedInstruction5<T0,T1,T2,T3,T4>(
01110             def,
01111             static_cast<RegisterRef<T0> *>(regRefs[0]),
01112             static_cast<RegisterRef<T1> *>(regRefs[1]),
01113             static_cast<RegisterRef<T2> *>(regRefs[2]),
01114             static_cast<RegisterRef<T3> *>(regRefs[3]),
01115             static_cast<RegisterRef<T4> *>(regRefs[4]));
01116     }
01117 
01118     // implement Instruction
01119     void describe(string& out, bool values) const
01120     {
01121         out = "CALL '";
01122         out += _def.getSignature();
01123         out += "' ";
01124         describeArg(out, values, _reg0);
01125         out += ", ";
01126         describeArg(out, values, _reg1);
01127         out += ", ";
01128         describeArg(out, values, _reg2);
01129         out += ", ";
01130         describeArg(out, values, _reg3);
01131         out += ", ";
01132         describeArg(out, values, _reg4);
01133     }
01134     void exec(TProgramCounter &pc) const
01135     {
01136         pc++;
01137         try {
01138             (*_def._functor)(_reg0,_reg1,_reg2,_reg3,_reg4);
01139         } catch (char const * str) {
01140             throw CalcMessage(str, pc - 1);
01141         }
01142     }
01143 };
01144 
01149 template <typename T0, typename T1, typename T2, typename T3, typename T4>
01150 class ExtendedInstruction5Context : public ExtendedInstruction
01151 {
01152 public:
01164     typedef void (*Functor)(
01165         boost::scoped_ptr<ExtendedInstructionContext>& ctx,
01166         RegisterRef<T0>* const reg0,
01167         RegisterRef<T1>* const reg1,
01168         RegisterRef<T2>* const reg2,
01169         RegisterRef<T3>* const reg3,
01170         RegisterRef<T4>* const reg4);
01171 
01175     typedef FunctorExtendedInstructionDef<
01176         ExtendedInstruction5Context<T0,T1,T2,T3,T4> > DefT;
01177 
01178 private:
01179     DefT _def;
01180     boost::scoped_ptr<ExtendedInstructionContext> _ctx;
01181     RegisterRef<T0>* _reg0;
01182     RegisterRef<T1>* _reg1;
01183     RegisterRef<T2>* _reg2;
01184     RegisterRef<T3>* _reg3;
01185     RegisterRef<T4>* _reg4;
01186 
01187 protected:
01188     // implement ExtendedInstruction
01189     ExtendedInstructionDef const &getDef() const
01190     {
01191         return _def;
01192     }
01193 
01194 public:
01195     explicit
01196     ExtendedInstruction5Context(
01197         DefT &def,
01198         RegisterRef<T0>* const reg0,
01199         RegisterRef<T1>* const reg1,
01200         RegisterRef<T2>* const reg2,
01201         RegisterRef<T3>* const reg3,
01202         RegisterRef<T4>* const reg4)
01203         : _def(def),
01204           _ctx(0),
01205           _reg0(reg0),
01206           _reg1(reg1),
01207           _reg2(reg2),
01208           _reg3(reg3),
01209           _reg4(reg4)
01210     {}
01211 
01212     static ExtendedInstruction5Context<T0,T1,T2,T3,T4> *create(
01213         DefT &def,
01214         vector<RegisterReference *> const &regRefs)
01215     {
01216         assert(regRefs.size() == 5);
01217         return new ExtendedInstruction5Context<T0,T1,T2,T3,T4>(
01218             def,
01219             static_cast<RegisterRef<T0> *>(regRefs[0]),
01220             static_cast<RegisterRef<T1> *>(regRefs[1]),
01221             static_cast<RegisterRef<T2> *>(regRefs[2]),
01222             static_cast<RegisterRef<T3> *>(regRefs[3]),
01223             static_cast<RegisterRef<T4> *>(regRefs[4]));
01224     }
01225 
01226     // implement Instruction
01227     void describe(string& out, bool values) const
01228     {
01229         out = "CALL '";
01230         out += _def.getSignature();
01231         out += "' ";
01232         describeArg(out, values, _reg0);
01233         out += ", ";
01234         describeArg(out, values, _reg1);
01235         out += ", ";
01236         describeArg(out, values, _reg2);
01237         out += ", ";
01238         describeArg(out, values, _reg3);
01239         out += ", ";
01240         describeArg(out, values, _reg4);
01241     }
01242     void exec(TProgramCounter &pc) const
01243     {
01244         pc++;
01245         try {
01246             // TODO: Remove this const cast. Ugly, but exec is defined as const
01247             // TODO: in virtual above.
01248             (*_def._functor)(
01249                 const_cast<boost::scoped_ptr<ExtendedInstructionContext>& >(
01250                     _ctx),
01251                 _reg0, _reg1, _reg2, _reg3, _reg4);
01252         } catch (char const * str) {
01253             throw CalcMessage(str, pc - 1);
01254         }
01255     }
01256 };
01257 
01258 
01259 FENNEL_END_NAMESPACE
01260 
01261 #endif
01262 
01263 // End ExtendedInstruction.h

Generated on Mon Jun 22 04:00:17 2009 for Fennel by  doxygen 1.5.1