00001
00002
00003
00004
00005
00006
00007
00008
00009 #ifndef EVAL_EXECUTION_CONTEXT_H
00010 #define EVAL_EXECUTION_CONTEXT_H
00011
00012 #include <typeinfo>
00013 #include <stdexcept>
00014 #include <vector>
00015 #include <map>
00016 #include <utility>
00017 #include <cstring>
00018
00019 #include <boost/static_assert.hpp>
00020 #include <boost/shared_array.hpp>
00021 #include <boost/type_traits/is_reference.hpp>
00022
00023 #include "fwrap.hpp"
00024
00025
00026 namespace eval
00027 {
00028 class execution_failure : public std::invalid_argument
00029 {
00030 public:
00031 explicit execution_failure(const std::string& err)
00032 : std::invalid_argument(err)
00033 {
00034 }
00035 };
00036
00037 class ambiguous_overload_exception : public execution_failure
00038 {
00039 public:
00040 explicit ambiguous_overload_exception(const std::string& err)
00041 : execution_failure("eval::ambiguous_overload_exception: '" + err + "'")
00042 {
00043 }
00044 };
00045
00046 class no_matching_function_exception : public execution_failure
00047 {
00048 public:
00049 explicit no_matching_function_exception(const std::string& err)
00050 : execution_failure("eval::no_matching_function_exception: method or function"
00051 " call failed '" + err + "'")
00052 {
00053 }
00054 };
00055
00056 class unknown_type_exception : public execution_failure
00057 {
00058 public:
00059 explicit unknown_type_exception(const std::string& type_name)
00060 : execution_failure("eval::unknown_type_exception: Unknown type '" + type_name + "'")
00061 {
00062 }
00063 };
00064
00065 class undefined_global_exception : public execution_failure
00066 {
00067 public:
00068 explicit undefined_global_exception(const std::string& name)
00069 : execution_failure("eval::undefined_global_exception: Unknown global '"
00070 + name + "'")
00071 {
00072 }
00073 };
00074
00075 class redefined_global_exception : public execution_failure
00076 {
00077 public:
00078 explicit redefined_global_exception(const std::string& name)
00079 : execution_failure("eval::redefined_global_exception: global '" + name
00080 + "' already defined")
00081 {
00082 }
00083 };
00084
00085
00086
00087 class bad_extended_val_cast : public execution_failure
00088 {
00089 public:
00090 bad_extended_val_cast(const std::string& type_from, const std::string& type_to)
00091 : execution_failure("eval::bad_extended_val_cast: from '" + type_from + "' to '"
00092 + type_to + "'")
00093 {
00094 }
00095 };
00096
00097
00098 namespace detail
00099 {
00100 struct type_info_ptr_compare
00101 {
00102 bool operator()(const std::type_info *lhs, const std::type_info *rhs) const
00103 {
00104 return lhs->before(*rhs);
00105 }
00106 };
00107
00109 class object_method_store
00110 {
00111 public:
00112 typedef std::multimap<std::string, fwrap>::const_iterator const_method_it_t;
00113 typedef std::multimap<std::string, fwrap>::iterator method_it_t;
00114
00115 object_method_store(const std::string& obj_name)
00116 : _obj_name(obj_name)
00117 {
00118 }
00119
00120 std::string get_obj_name() const
00121 {
00122 return _obj_name;
00123 }
00124
00125 void add_method(const std::string& method_name, const fwrap& m)
00126 {
00127 _methods.insert(std::pair<std::string, fwrap>(method_name, m));
00128 }
00129
00130 std::pair<const_method_it_t, const_method_it_t>
00131 get_methods(const std::string& method_name) const
00132 {
00133 return _methods.equal_range(method_name);
00134 }
00135
00136 void add_static_method(const std::string& static_method_name, const fwrap& m)
00137 {
00138 _static_methods.insert(std::pair<std::string, fwrap>(static_method_name, m));
00139 }
00140
00141 std::pair<const_method_it_t, const_method_it_t>
00142 get_static_methods(const std::string& method_name) const
00143 {
00144 return _static_methods.equal_range(method_name);
00145 }
00146
00148 void delete_methods(const std::string& method_name)
00149 {
00150 std::pair<method_it_t, method_it_t> remove_range;
00151
00152 remove_range = _methods.equal_range(method_name);
00153 _methods.erase(remove_range.first, remove_range.second);
00154
00155 remove_range = _static_methods.equal_range(method_name);
00156 _static_methods.erase(remove_range.first, remove_range.second);
00157 }
00158 private:
00159 std::string _obj_name;
00160 std::multimap<std::string, fwrap> _methods;
00161 std::multimap<std::string, fwrap> _static_methods;
00162 };
00163
00167 class type_info_conversion_store
00168 {
00169 public:
00170 type_info_conversion_store(const std::type_info *from, const std::type_info *to)
00171 : _from(from), _to(to)
00172 {
00173 }
00174
00175 bool operator<(const type_info_conversion_store& rhs) const
00176 {
00177 return *_from == *rhs._from ? _to->before(*rhs._to) : _from->before(*rhs._from);
00178 }
00179
00180 private:
00181 const std::type_info * _from;
00182 const std::type_info * _to;
00183 };
00184
00186 enum conversion_rank {
00187 CONVERSION_EXACT_MATCH = 300,
00188 CONVERSION_QUALIFICATION = 200,
00189 CONVERSION_OTHER_CONVERSION = 100,
00190 CONVERSION_IMPOSSIBLE = -1
00191 };
00192
00193
00196 template<typename Iterator1, typename Iterator2>
00197 bool strictly_greater_or_equal_all(Iterator1 begin1, Iterator1 end1, Iterator2 begin2)
00198 {
00199 bool elements_all_equal = true;
00200 for( ; begin1 != end1; ++begin1, ++begin2)
00201 {
00202 if(*begin1 < *begin2)
00203 {
00204 return false;
00205 }
00206 else if(*begin1 > *begin2)
00207 {
00208 elements_all_equal = false;
00209 }
00210 }
00211 return !elements_all_equal;
00212 }
00213
00214
00215
00216
00217 }
00218
00225 class execution_context
00226 {
00227 public:
00228 typedef val(*val_convert_t)(val& v);
00229
00230 execution_context()
00231 : _initialized(false)
00232 {
00233 }
00234
00241 virtual void register_all()
00242 {
00243 if(!_initialized)
00244 {
00245 _initialized = true;
00246 this->register_functions();
00247 this->register_methods_and_ctors();
00248 this->register_types();
00249 this->register_conversions();
00250 }
00251 }
00252
00258 bool point_to_same_obj(val& lhs, val& rhs) const;
00259
00265 template<typename DesiredT>
00266 DesiredT *extended_val_cast_ptr(val& v) const;
00267
00273 template<typename DesiredT>
00274 DesiredT extended_val_cast_value(val& v) const;
00275
00276
00288 val val_cast_conversion_string(val& v, const std::string& desired_type,
00289 bool can_use_temp) const;
00290
00299 val call(fwrap& f, fwrap_args& args);
00300
00303 val call_function(const std::string& fn_name, fwrap_args& args);
00304
00309 val call_method(const std::string& m_name, fwrap_args& args);
00310
00315 val call_function_or_method(const std::string& name, fwrap_args& args);
00316
00318 val& get_global(const std::string& name);
00319
00321 const val& get_global(const std::string& name) const;
00322
00324 void add_global(const std::string& name, const val& v);
00325
00326 val& operator[](const std::string& name);
00327
00328 void clear_globals();
00329
00330 virtual ~execution_context();
00331
00332 protected:
00333 virtual void register_functions()
00334 {
00335 }
00336
00337 virtual void register_methods_and_ctors()
00338 {
00339 }
00340
00341 virtual void register_types()
00342 {
00343 }
00344
00345 virtual void register_conversions()
00346 {
00347 }
00348
00349 std::multimap<std::string, fwrap> _functions;
00350 std::map<const std::type_info *,
00351 detail::object_method_store *,
00352 detail::type_info_ptr_compare
00353 > _objects;
00354 std::map<std::string, const std::type_info *> _types;
00355 std::map<detail::type_info_conversion_store, val_convert_t> _ptr_conversions;
00356 std::map<detail::type_info_conversion_store, val_convert_t> _value_conversions;
00357 std::map<std::string, val> _globals;
00358
00359 typedef std::multimap<std::string, fwrap>::const_iterator fwrap_it_t;
00360
00361
00362 private:
00363 bool _initialized;
00364
00365 val val_cast_conversion(val& v, const std::type_info *desired_type,
00366 bool can_use_temp) const;
00367
00368 std::pair<fwrap, bool> find_best_match(std::pair<fwrap_it_t, fwrap_it_t>& candidate_range,
00369 fwrap_args::iterator args_begin, fwrap_args::iterator args_end,
00370 fwrap_args& best_match_args,
00371 std::vector<detail::conversion_rank>& best_match_rank);
00372
00373 void throw_if_match_invalid(const std::string& name, std::pair<fwrap, bool>& best_match,
00374 fwrap_args& args);
00375
00376 std::string type_name(const std::type_info *type) const;
00377
00378 std::string format_fn_call_debug(const std::string& fn_name, fwrap_args& args) const;
00379
00380 void remove_aliasing(val& v, fwrap& f, fwrap_args::iterator orig_arg_it,
00381 fwrap_args::iterator actual_arg_it);
00382
00384 execution_context(const execution_context& e);
00385
00387 execution_context& operator=(const execution_context& rhs);
00388 };
00389
00390
00391
00392 inline bool execution_context::point_to_same_obj(val& lhs, val& rhs) const
00393 {
00394 if(lhs.type() != rhs.type())
00395 {
00396 detail::type_info_conversion_store conv_id(&lhs.type(), &rhs.type());
00397 std::map<detail::type_info_conversion_store, val_convert_t>::const_iterator it;
00398 it = _ptr_conversions.find(conv_id);
00399 if(it != _ptr_conversions.end())
00400 {
00401 val conv_lhs(it->second(lhs));
00402 return conv_lhs.points_to_same_object_as(rhs);
00403 }
00404 }
00405 return lhs.points_to_same_object_as(rhs);
00406 }
00407
00408 template<typename DesiredT>
00409 inline DesiredT *execution_context::extended_val_cast_ptr(val& v) const
00410 {
00411 BOOST_STATIC_ASSERT(!boost::is_reference<DesiredT>::value);
00412 val converted_val(val_cast_conversion(v, &typeid(DesiredT), false));
00413 if(converted_val.empty())
00414 {
00415 throw bad_extended_val_cast(type_name(&v.type()), type_name(&typeid(DesiredT)));
00416 }
00417 return val_cast_ptr<DesiredT>(converted_val);
00418 }
00419
00420 template<typename DesiredT>
00421 inline DesiredT execution_context::extended_val_cast_value(val& v) const
00422 {
00423 BOOST_STATIC_ASSERT(!boost::is_reference<DesiredT>::value);
00424 val converted_val(val_cast_conversion(v, &typeid(DesiredT), true));
00425 if(converted_val.empty())
00426 {
00427 throw bad_extended_val_cast(type_name(&v.type()), type_name(&typeid(DesiredT)));
00428 }
00429 return *val_cast_ptr<DesiredT>(converted_val);
00430 }
00431
00432 inline val execution_context::val_cast_conversion_string(val& v,
00433 const std::string& desired_type, bool can_use_temp) const
00434 {
00435 std::map<std::string, const std::type_info *>::const_iterator type_it;
00436 type_it = _types.find(desired_type);
00437 if(type_it == _types.end())
00438 {
00439 throw unknown_type_exception(desired_type);
00440 }
00441 val converted_val(val_cast_conversion(v, type_it->second, can_use_temp));
00442 if(converted_val.empty())
00443 {
00444 throw bad_extended_val_cast(type_name(&v.type()), desired_type);
00445 }
00446 return converted_val;
00447 }
00448
00449
00450 inline val execution_context::call(fwrap& f, fwrap_args& args)
00451 {
00452
00453
00454 std::multimap<std::string, fwrap> temp;
00455 temp.insert(std::pair<std::string, fwrap>("temp", f));
00456
00457 std::pair<fwrap_it_t, fwrap_it_t> candidate_range(temp.begin(), temp.end());
00458 fwrap_args best_match_args;
00459 std::vector<detail::conversion_rank> best_match_rank;
00460
00461 std::pair<fwrap, bool> best_match(find_best_match(candidate_range,
00462 args.begin(), args.end(),
00463 best_match_args, best_match_rank));
00464
00465 throw_if_match_invalid("unnamed_fwrap_object", best_match, args);
00466 val rv(best_match.first(best_match_args));
00467 remove_aliasing(rv, best_match.first, args.begin(), best_match_args.begin());
00468
00469 return rv;
00470
00471 }
00472
00473
00474 inline val execution_context::call_function(const std::string& fn_name, fwrap_args& args)
00475 {
00476 std::pair<fwrap_it_t, fwrap_it_t> candidate_range(_functions.equal_range(fn_name));
00477 fwrap_args best_match_args;
00478 std::vector<detail::conversion_rank> best_match_rank;
00479
00480 std::pair<fwrap, bool> best_match(find_best_match(candidate_range,
00481 args.begin(), args.end(),
00482 best_match_args, best_match_rank));
00483
00484 throw_if_match_invalid(fn_name, best_match, args);
00485 val rv(best_match.first(best_match_args));
00486 remove_aliasing(rv, best_match.first, args.begin(), best_match_args.begin());
00487
00488 return rv;
00489 }
00490
00491
00492 inline val execution_context::call_method(const std::string& m_name, fwrap_args& args)
00493 {
00494 std::map<const std::type_info *, detail::object_method_store *,
00495 detail::type_info_ptr_compare>::iterator type_it;
00496 type_it = _objects.find(&args.at(0).type());
00497 if(type_it == _objects.end())
00498 {
00499 throw unknown_type_exception(args[0].type().name());
00500 }
00501
00502 std::pair<fwrap_it_t, fwrap_it_t> candidate_range_method(
00503 type_it->second->get_methods(m_name));
00504 fwrap_args best_match_args_method;
00505 std::vector<detail::conversion_rank> best_match_rank_method;
00506 std::pair<fwrap, bool> best_match_method(find_best_match(candidate_range_method,
00507 args.begin(), args.end(),
00508 best_match_args_method, best_match_rank_method));
00509
00510 std::pair<fwrap_it_t, fwrap_it_t> candidate_range_static(
00511 type_it->second->get_static_methods(m_name));
00512 fwrap_args best_match_args_static;
00513 std::vector<detail::conversion_rank> best_match_rank_static;
00514 std::pair<fwrap, bool> best_match_static(find_best_match(candidate_range_static,
00515 args.begin() + 1, args.end(),
00516 best_match_args_static, best_match_rank_static));
00517
00518 std::pair<fwrap, bool> *best_match = &best_match_method;
00519 fwrap_args *best_match_args = &best_match_args_method;
00520 int is_static_offset = 0;
00521 if(!best_match_static.first.is_null())
00522 {
00523 if(best_match_method.first.is_null()
00524 || detail::strictly_greater_or_equal_all(best_match_rank_static.begin(),
00525 best_match_rank_static.end(),
00526 best_match_rank_method.begin() + 1))
00527 {
00528 best_match = &best_match_static;
00529 best_match_args = &best_match_args_static;
00530 is_static_offset = 1;
00531 }
00532 else if(detail::strictly_greater_or_equal_all(best_match_rank_method.begin() + 1,
00533 best_match_rank_method.end(),
00534 best_match_rank_static.begin()))
00535 {
00536
00537 }
00538 else
00539 {
00540 best_match->second = true;
00541 }
00542 }
00543
00544 throw_if_match_invalid(m_name, *best_match, args);
00545 val rv(best_match->first(*best_match_args));
00546 remove_aliasing(rv, best_match->first, args.begin() + is_static_offset,
00547 best_match_args->begin());
00548
00549 return rv;
00550 }
00551
00552 inline val execution_context::call_function_or_method(const std::string& name,
00553 fwrap_args& args)
00554 {
00555 std::pair<fwrap_it_t, fwrap_it_t> candidate_range_func(_functions.equal_range(name));
00556 fwrap_args best_match_args_func;
00557 std::vector<detail::conversion_rank> best_match_rank_func;
00558
00559 std::pair<fwrap, bool> best_match_func(find_best_match(candidate_range_func,
00560 args.begin(), args.end(),
00561 best_match_args_func, best_match_rank_func));
00562
00563 std::map<const std::type_info *, detail::object_method_store *,
00564 detail::type_info_ptr_compare>::iterator type_it;
00565 type_it = _objects.find(&args.at(0).type());
00566 if(type_it == _objects.end())
00567 {
00568
00569
00570 throw unknown_type_exception(args[0].type().name());
00571 }
00572
00573 std::pair<fwrap_it_t, fwrap_it_t> candidate_range_method(
00574 type_it->second->get_methods(name));
00575 fwrap_args best_match_args_method;
00576 std::vector<detail::conversion_rank> best_match_rank_method;
00577 std::pair<fwrap, bool> best_match_method(find_best_match(candidate_range_method,
00578 args.begin(), args.end(),
00579 best_match_args_method, best_match_rank_method));
00580
00581 std::pair<fwrap, bool> *best_match = &best_match_method;
00582 fwrap_args *best_match_args = &best_match_args_method;
00583 if(!best_match_func.first.is_null())
00584 {
00585 if(best_match_method.first.is_null()
00586 || detail::strictly_greater_or_equal_all(best_match_rank_func.begin(),
00587 best_match_rank_func.end(),
00588 best_match_rank_method.begin()))
00589 {
00590 best_match = &best_match_func;
00591 best_match_args = &best_match_args_func;
00592 }
00593 else if(detail::strictly_greater_or_equal_all(best_match_rank_method.begin(),
00594 best_match_rank_method.end(),
00595 best_match_rank_func.begin()))
00596 {
00597
00598 }
00599 else
00600 {
00601 best_match->second = true;
00602 }
00603 }
00604
00605 throw_if_match_invalid(name, *best_match, args);
00606 val rv(best_match->first(*best_match_args));
00607 remove_aliasing(rv, best_match->first, args.begin(), best_match_args->begin());
00608
00609 return rv;
00610 }
00611
00612
00613
00614 val& execution_context::get_global(const std::string& name)
00615 {
00616 std::map<std::string, val>::iterator it;
00617 it = _globals.find(name);
00618 if(it == _globals.end())
00619 {
00620 throw undefined_global_exception(name);
00621 }
00622 return it->second;
00623 }
00624
00625 const val& execution_context::get_global(const std::string& name) const
00626 {
00627 std::map<std::string, val>::const_iterator it;
00628 it = _globals.find(name);
00629 if(it == _globals.end())
00630 {
00631 throw undefined_global_exception(name);
00632 }
00633 return it->second;
00634 }
00635
00636 void execution_context::add_global(const std::string& name, const val& v)
00637 {
00638 std::pair<std::map<std::string, val>::iterator, bool> rv(_globals.insert(
00639 std::pair<std::string, val>(name, v)));
00640 if(!rv.second)
00641 {
00642 throw redefined_global_exception(name);
00643 }
00644 }
00645
00646 val& execution_context::operator[](const std::string& name)
00647 {
00648 return _globals[name];
00649 }
00650
00651 void execution_context::clear_globals()
00652 {
00653 _globals.clear();
00654 }
00655
00656 inline execution_context::~execution_context()
00657 {
00658 std::map<const std::type_info *, detail::object_method_store *,
00659 detail::type_info_ptr_compare>::iterator it;
00660 for(it = _objects.begin(); it != _objects.end(); ++it)
00661 {
00662 delete it->second;
00663 }
00664 }
00665
00666
00667
00668 inline val execution_context::val_cast_conversion(val& v, const std::type_info *desired_type,
00669 bool can_use_temp) const
00670 {
00671 detail::type_info_conversion_store conv_id(&v.type(), desired_type);
00672 std::map<detail::type_info_conversion_store, val_convert_t>::const_iterator it;
00673 it = _ptr_conversions.find(conv_id);
00674 if(it == _ptr_conversions.end())
00675 {
00676 if(!can_use_temp)
00677 {
00678 return val();
00679 }
00680
00681 it = _value_conversions.find(conv_id);
00682 if(it == _value_conversions.end())
00683 {
00684 return val();
00685 }
00686 }
00687 return it->second(v);
00688 }
00689
00690
00692 inline std::pair<fwrap, bool> execution_context::find_best_match(
00693 std::pair<fwrap_it_t, fwrap_it_t>& candidate_range,
00694 fwrap_args::iterator args_begin, fwrap_args::iterator args_end,
00695 fwrap_args& best_match_args,
00696 std::vector<detail::conversion_rank>& best_match_rank)
00697 {
00698 fwrap best_match;
00699 bool best_match_ambiguous = false;
00700
00701 for(fwrap_it_t it = candidate_range.first; it != candidate_range.second; ++it)
00702 {
00703 const fwrap& curr_match = it->second;
00704 std::vector<detail::conversion_rank> curr_match_rank;
00705 fwrap_args curr_match_args;
00706
00707 if(static_cast<int>(curr_match.arity()) != std::distance(args_begin, args_end))
00708 {
00709 continue;
00710 }
00711
00712 std::vector<arg_info> arg_meta;
00713 curr_match.get_arg_info(arg_meta);
00714 std::vector<arg_info>::const_iterator arg_meta_it = arg_meta.begin();
00715 fwrap_args::iterator args_it = args_begin;
00716 for( ; args_it != args_end; args_it++, arg_meta_it++)
00717 {
00718 if(args_it->empty())
00719 {
00720 if(!arg_meta_it->is_pointer())
00721 {
00722 goto try_next_fn;
00723 }
00724 curr_match_rank.push_back(detail::CONVERSION_OTHER_CONVERSION);
00725 curr_match_args.push_back(*args_it);
00726 }
00727 else
00728 {
00729
00730 if(args_it->is_const() && !arg_meta_it->is_const())
00731 {
00732 goto try_next_fn;
00733 }
00734 if(args_it->type() == arg_meta_it->type())
00735 {
00736 if(args_it->is_const() == arg_meta_it->is_const()
00737 || (!arg_meta_it->is_pointer() && !arg_meta_it->is_reference()))
00738 {
00739 curr_match_rank.push_back(detail::CONVERSION_EXACT_MATCH);
00740 }
00741 else
00742 {
00743 curr_match_rank.push_back(detail::CONVERSION_QUALIFICATION);
00744 }
00745 curr_match_args.push_back(*args_it);
00746 }
00747 else
00748 {
00749 bool can_use_temp = !arg_meta_it->is_pointer()
00750 && (!arg_meta_it->is_reference() || arg_meta_it->is_const());
00751 val converted_val(val_cast_conversion(*args_it, &arg_meta_it->type(),
00752 can_use_temp));
00753 if(converted_val.empty())
00754 {
00755 goto try_next_fn;
00756 }
00757 curr_match_rank.push_back(detail::CONVERSION_OTHER_CONVERSION);
00758 curr_match_args.push_back(converted_val);
00759 }
00760 }
00761 }
00762 if(best_match.is_null()
00763 || detail::strictly_greater_or_equal_all(curr_match_rank.begin(),
00764 curr_match_rank.end(),
00765 best_match_rank.begin()))
00766 {
00767 best_match = curr_match;
00768 best_match_args = curr_match_args;
00769 best_match_rank = curr_match_rank;
00770 best_match_ambiguous = false;
00771 }
00772 else if(detail::strictly_greater_or_equal_all(best_match_rank.begin(),
00773 best_match_rank.end(),
00774 curr_match_rank.begin()))
00775 {
00776
00777 }
00778 else
00779 {
00780
00781 best_match_ambiguous = true;
00782 }
00783
00784 try_next_fn:
00785 ;
00786 }
00787 return std::pair<fwrap, bool>(best_match, best_match_ambiguous);
00788 }
00789
00790 inline void execution_context::throw_if_match_invalid(const std::string& name,
00791 std::pair<fwrap, bool>& best_match,
00792 fwrap_args& args)
00793 {
00794 if(best_match.first.is_null())
00795 {
00796 throw no_matching_function_exception(format_fn_call_debug(name, args));
00797 }
00798 if(best_match.second)
00799 {
00800 throw ambiguous_overload_exception(format_fn_call_debug(name, args));
00801 }
00802 }
00803
00804 inline std::string execution_context::type_name(const std::type_info *type) const
00805 {
00806 std::map<const std::type_info *, detail::object_method_store *,
00807 detail::type_info_ptr_compare>::const_iterator type_it;
00808 type_it = _objects.find(type);
00809 std::string rv;
00810 if(type_it == _objects.end())
00811 {
00812 rv = "[unregistered type] ";
00813 rv += type->name();
00814 }
00815 else
00816 {
00817 rv = type_it->second->get_obj_name();
00818 }
00819 return rv;
00820 }
00821
00822
00823 inline std::string execution_context::format_fn_call_debug(const std::string& fn_name,
00824 fwrap_args& args) const
00825 {
00826 std::string rv(fn_name);
00827 rv += "(";
00828 for(fwrap_args::const_iterator arg_it = args.begin(); arg_it != args.end(); ++arg_it)
00829 {
00830 if(arg_it != args.begin())
00831 {
00832 rv += ", ";
00833 }
00834
00835 rv += type_name(&arg_it->type());
00836 if(arg_it->is_const())
00837 {
00838 rv += " const";
00839 }
00840 }
00841 rv += ")";
00842 return rv;
00843 }
00844
00845 inline void execution_context::remove_aliasing(val& v, fwrap& f,
00846 fwrap_args::iterator orig_arg_it,
00847 fwrap_args::iterator actual_arg_it)
00848 {
00849 arg_info rv_arg_meta(f.get_rv_info());
00850 if(!rv_arg_meta.is_pointer() && !rv_arg_meta.is_reference())
00851 {
00852 return;
00853 }
00854 std::vector<arg_info> arg_meta;
00855 f.get_arg_info(arg_meta);
00856 std::vector<arg_info>::const_iterator arg_meta_it = arg_meta.begin();
00857 for( ; arg_meta_it != arg_meta.end(); arg_meta_it++, orig_arg_it++, actual_arg_it++)
00858 {
00859 if(arg_meta_it->is_reference() || arg_meta_it->is_pointer())
00860 {
00861 if(point_to_same_obj(v, *orig_arg_it))
00862 {
00863 v = *orig_arg_it;
00864 break;
00865 }
00866
00867
00868
00869 if(arg_meta_it->is_const() && arg_meta_it->is_reference())
00870 {
00871 if(point_to_same_obj(v, *actual_arg_it))
00872 {
00873 v = *actual_arg_it;
00874 break;
00875 }
00876 }
00877 }
00878 }
00879 }
00880
00881
00882 }
00883
00884
00885
00886
00887 #endif
00888
00889