00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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 ¶meterTypes)
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 ®s) = 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 ¶meterTypes,
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
00138 ExtendedInstruction *createInstruction(
00139 vector<RegisterReference *> const ®s)
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
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
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 ®Refs)
00236 {
00237 assert(regRefs.size() == 0);
00238 return new ExtendedInstruction0(def);
00239 }
00240
00241
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
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 ®Refs)
00300 {
00301 assert(regRefs.size() == 0);
00302 return new ExtendedInstruction0Context(def);
00303 }
00304
00305
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
00317
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
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 ®Refs)
00370 {
00371 assert(regRefs.size() == 1);
00372
00373 return new ExtendedInstruction1<T0>(
00374 def,
00375 static_cast<RegisterRef<T0> *>(regRefs[0]));
00376 }
00377
00378
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
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 ®Refs)
00446 {
00447 assert(regRefs.size() == 1);
00448
00449 return new ExtendedInstruction1Context<T0>(
00450 def,
00451 static_cast<RegisterRef<T0> *>(regRefs[0]));
00452 }
00453
00454
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
00467
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
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 ®Refs)
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
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
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 ®Refs)
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
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
00639
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
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 ®Refs)
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
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
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 ®Refs)
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
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
00827
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
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 ®Refs)
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
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
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 ®Refs)
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
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
01029
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
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 ®Refs)
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
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
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 ®Refs)
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
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
01247
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