00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
00044
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
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
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
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
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
00138 virtual bool equal(void* p0, void* p1) const;
00139
00140
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
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
00266
00267
00268
00269
00270 ct_proto* make_proto(ct_type const* arg0, ...);
00271
00272 }}
00273
00274 #endif