Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

more/lang/ct_proto.h

Go to the documentation of this file.
00001 //  Copyright (C) 2001  Petter Urkedal (petter.urkedal@matfys.lth.se)
00002 //
00003 //  This file is free software; you can redistribute it and/or modify
00004 //  it under the terms of the GNU General Public License as published by
00005 //  the Free Software Foundation; either version 2 of the License, or
00006 //  (at your option) any later version.
00007 //
00008 //  This file is distributed in the hope that it will be useful,
00009 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00011 //  GNU General Public License for more details.
00012 //
00013 //  You should have received a copy of the GNU General Public License
00014 //  along with this program; if not, write to the Free Software
00015 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 //
00017 //  As a special exception, you may use this file as part of a free
00018 //  software library without restriction.  Specifically, if other files
00019 //  instantiate templates or use macros or inline functions from this
00020 //  file, or you compile this file and link it with other files to
00021 //  produce an executable, this file does not by itself cause the
00022 //  resulting executable to be covered by the GNU General Public
00023 //  License.  This exception does not however invalidate any other
00024 //  reasons why the executable file might be covered by the GNU General
00025 //  Public License.
00026 //
00027 //  $Id: ct_proto.h,v 1.1 2002/05/30 18:01:37 petter_urkedal Exp $
00028 
00029 
00030 #ifndef MORE_LANG_CT_PROTO_H
00031 #define MORE_LANG_CT_PROTO_H
00032 
00033 #include <more/lang/ct_type.h>
00034 #include <stdexcept>
00035 #include <stdarg.h>
00036 #ifndef MORE_LANG_USE_FFI
00037 # include <more/lang/location.h>
00038 #endif
00039 
00040 namespace more {
00041 namespace lang {
00042 
00043   /** \class ct_proto ct_proto.h more/lang/ct_proto.h
00044       The runtime representation of a prototype. */
00045   struct ct_proto : ct_type
00046   {
00047       typedef std::size_t size_type;
00048       typedef ct_type const* arg_type_type;
00049       typedef ct_type const** arg_type_mutable_iterator;
00050       typedef ct_type const* const* arg_type_iterator;
00051 
00052       explicit ct_proto(size_type n_args, ct_type const* t_res = 0);
00053 
00054       virtual ~ct_proto();
00055       virtual ct_proto* clone() const;
00056 
00057       /** Set the type of argument number \a i. */
00058       void
00059       set_arg_type(size_type i, ct_type const* t)
00060       {
00061 #ifndef MORE_LANG_NDEBUG
00062           req_not_frozen();
00063           if (i >= m_arg_count)
00064               throw std::out_of_range("more::lang::ct_proto::arg_type: "
00065                                       "Argument index out of range.");
00066           if (m_arg_arr[i])
00067               throw std::logic_error("more::lang::ct_proto: "
00068                                      "Redefinition of argument type.");
00069 #endif
00070           m_arg_arr[i] = t;
00071       }
00072 
00073       /** Return the type of argument number \a i. */
00074       ct_type const*
00075       arg_type(size_type i) const
00076       {
00077 #ifndef MORE_LANG_NDEBUG
00078           req_frozen();
00079           if (i >= m_arg_count)
00080               throw std::out_of_range("more::lang::ct_proto::arg_type: "
00081                                       "Argument index out of range.");
00082 #endif
00083           return m_arg_arr[i];
00084       }
00085 
00086       /** Set the type of the return value. */
00087       void
00088       set_result_type(ct_type const* rc)
00089       {
00090 #ifndef MORE_LANG_NDEBUG
00091           req_not_frozen();
00092           if (m_result_type)
00093               throw std::logic_error("more::lang::ct_proto: "
00094                                      "Redefinition of result type.");
00095 #endif
00096           m_result_type = rc;
00097       }
00098 
00099       /** The type of the return value. */
00100       ct_type const* result_type() const { return m_result_type; }
00101 
00102       void call(fn_ptr_t f, void* ret, void** args) const;
00103       bool is_frozen() const { return m_frozen_p == 1; }
00104       void freeze() { if (!is_frozen()) finish(); }
00105 
00106       size_type arg_count() const { req_frozen(); return m_arg_count; }
00107       size_type arg_count_this_far() const { return m_arg_count; }
00108 
00109       arg_type_mutable_iterator
00110       arg_type_mutable_begin()
00111       {
00112           return m_arg_arr;
00113       }
00114       arg_type_mutable_iterator
00115       arg_type_mutable_end()
00116       {
00117           return m_arg_arr + m_arg_count;
00118       }
00119       arg_type_iterator
00120       arg_type_begin() const
00121       {
00122           req_frozen();
00123           return m_arg_arr;
00124       }
00125       arg_type_iterator
00126       arg_type_end() const
00127       {
00128           req_frozen();
00129           return m_arg_arr + m_arg_count;
00130       }
00131 
00132 #ifdef MORE_LANG_PROVIDE_FFI
00133       virtual ffi_type* ffi_type_of() const;
00134 #endif
00135       virtual void      destruct(void* p) const;
00136 
00137       /** True iff the fuction pointers pointed to by p0 and p1 are equal. */
00138       virtual bool      equal(void* p0, void* p1) const;
00139 
00140 //        virtual void construct(void* p) const;
00141       virtual void      construct_copy(void* p, void* src) const;
00142 
00143       virtual void      print_declaration_pre(std::ostream&,
00144                                               printopt_type) const;
00145       virtual void      print_declaration_post(std::ostream&,
00146                                                printopt_type) const;
00147       void      print_declaration_post(std::ostream&, printopt_type,
00148                                        cx_identifier const* const* args) const;
00149       virtual void      hash(hash_type&) const;
00150       virtual bool      equal_to(ct_type const*) const;
00151 
00152     private:
00153       void reserve(size_type);
00154       void finish();
00155       void req_not_frozen() const
00156       {
00157           if (is_frozen())
00158               throw std::logic_error("more::lang::ct_proto: Frozen.");
00159       }
00160       void req_frozen() const
00161       {
00162           if (!is_frozen())
00163               throw std::logic_error("more::lang::ct_proto: Not frozen.");
00164       }
00165 
00166       arg_type_type*            m_arg_arr;
00167       size_type                 m_arg_count;
00168       ct_type const*            m_result_type;
00169 #ifdef MORE_LANG_USE_FFI
00170       ffi_type**                m_ffi_arg_types;
00171       mutable ffi_cif           m_cif;
00172 #else
00173       location                  m_adaptor;
00174       static package*           s_adaptor_pkg;
00175 #endif
00176       unsigned int              m_frozen_p : 1;
00177   };
00178 
00179   ///\if bits
00180   template <typename Result>
00181     struct _ct_type<Result (*)()>
00182     {
00183         static ct_type const* get()
00184         {
00185             static ct_pointer* t = 0;
00186             if (!t) {
00187                 ct_proto* t0 = new(UseGC) ct_proto(0, ct_type_of<Result>());
00188                 t0->freeze();
00189                 t = new(UseGC) ct_pointer(t0);
00190             }
00191             return t;
00192         }
00193     };
00194 
00195   template <typename Arg0, typename Result>
00196     struct _ct_type<Result (*)(Arg0)>
00197     {
00198         static ct_type const* get()
00199         {
00200             static ct_pointer* t = 0;
00201             if (!t) {
00202                 ct_proto* t0 = new(UseGC) ct_proto(1, ct_type_of<Result>());
00203                 t0->set_arg_type(0, ct_type_of<Arg0>());
00204                 t0->freeze();
00205                 t = new(UseGC) ct_pointer(t0);
00206             }
00207             return t;
00208         }
00209     };
00210 
00211   template <typename Arg0, typename Arg1, typename Result>
00212     struct _ct_type<Result (*)(Arg0, Arg1)>
00213     {
00214         static ct_type const* get()
00215         {
00216             static ct_pointer* t = 0;
00217             if (!t) {
00218                 ct_proto* t0 = new(UseGC) ct_proto(2, ct_type_of<Result>());
00219                 t0->set_arg_type(0, ct_type_of<Arg0>());
00220                 t0->set_arg_type(1, ct_type_of<Arg1>());
00221                 t0->freeze();
00222                 t = new(UseGC) ct_pointer(t0);
00223             }
00224             return t;
00225         }
00226     };
00227 
00228   template <typename Arg0, typename Arg1, typename Arg2, typename Result>
00229     struct _ct_type<Result (*)(Arg0, Arg1, Arg2)>
00230     {
00231         static ct_type const* get()
00232         {
00233             static ct_pointer* t = 0;
00234             if (!t) {
00235                 ct_proto* t0 = new(UseGC) ct_proto(3, ct_type_of<Result>());
00236                 t0->set_arg_type(0, ct_type_of<Arg0>());
00237                 t0->set_arg_type(1, ct_type_of<Arg1>());
00238                 t0->set_arg_type(2, ct_type_of<Arg2>());
00239                 t0->freeze();
00240                 t = new(UseGC) ct_pointer(t0);
00241             }
00242             return t;
00243         }
00244     };
00245 
00246   template < typename Arg0, typename Arg1, typename Arg2, typename Arg3,
00247              typename Result >
00248     struct _ct_type<Result (*)(Arg0, Arg1, Arg2, Arg3)>
00249     {
00250         static ct_type const* get()
00251         {
00252             static ct_pointer* t = 0;
00253             if (!t) {
00254                 ct_proto* t0 = new(UseGC) ct_proto(4, ct_type_of<Result>());
00255                 t0->set_arg_type(0, ct_type_of<Arg0>());
00256                 t0->set_arg_type(1, ct_type_of<Arg1>());
00257                 t0->set_arg_type(2, ct_type_of<Arg2>());
00258                 t0->set_arg_type(3, ct_type_of<Arg3>());
00259                 t0->freeze();
00260                 t = new(UseGC) ct_pointer(t0);
00261             }
00262             return t;
00263         }
00264     };
00265   ///\endif
00266 
00267   /** Make a prototype with given arguments and result type.  The
00268       argument types are listed first, followed by the result type,
00269       followed by \c (ct_type*)0. */
00270   ct_proto* make_proto(ct_type const* arg0, ...);
00271 
00272 }}
00273 
00274 #endif

Generated on Sat Sep 7 19:11:17 2002 for more with Doxygen 1.2.13.1. Doxygen 1.2.13.1 is written and copyright 1997-2002 by Dimitri van Heesch.