Add object dependency tracking to make sure that during nested function calls all returned values are not prematurely destructed.
All tests pass on vc2008 now.
This commit is contained in:
parent
43dbd8ac78
commit
74e719c053
@ -70,10 +70,15 @@ namespace chaiscript
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Data()
|
||||
{
|
||||
}
|
||||
|
||||
Type_Info m_type_info;
|
||||
boost::any m_obj;
|
||||
bool m_is_ref;
|
||||
boost::function<bool (boost::any*)> m_is_null;
|
||||
std::vector<boost::shared_ptr<Data> > m_dependencies;
|
||||
};
|
||||
|
||||
struct Object_Data
|
||||
@ -245,6 +250,24 @@ namespace chaiscript
|
||||
return !is_ref();
|
||||
}
|
||||
|
||||
void clear_dependencies()
|
||||
{
|
||||
m_data->m_dependencies.clear();
|
||||
}
|
||||
|
||||
template<typename InItr>
|
||||
void add_dependencies(InItr begin, const InItr &end)
|
||||
{
|
||||
while (begin != end)
|
||||
{
|
||||
if (begin->m_data != m_data)
|
||||
{
|
||||
m_data->m_dependencies.push_back(begin->m_data);
|
||||
}
|
||||
++begin;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
boost::shared_ptr<Data> m_data;
|
||||
|
@ -132,10 +132,6 @@ namespace chaiscript
|
||||
|
||||
virtual ~Dispatch_Function() {}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
return dispatch(m_funcs.begin(), m_funcs.end(), params);
|
||||
}
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
@ -167,6 +163,12 @@ namespace chaiscript
|
||||
return "";
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
return dispatch(m_funcs.begin(), m_funcs.end(), params);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<std::string, Proxy_Function > > m_funcs;
|
||||
};
|
||||
|
@ -90,15 +90,6 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
if (dynamic_object_typename_match(params, m_type_name, m_ti))
|
||||
{
|
||||
return (*m_func)(params);
|
||||
} else {
|
||||
throw guard_error();
|
||||
}
|
||||
}
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
@ -111,6 +102,16 @@ namespace chaiscript
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
if (dynamic_object_typename_match(params, m_type_name, m_ti))
|
||||
{
|
||||
return (*m_func)(params);
|
||||
} else {
|
||||
throw guard_error();
|
||||
}
|
||||
}
|
||||
|
||||
virtual bool compare_first_type(const Boxed_Value &bv) const
|
||||
{
|
||||
return dynamic_object_typename_match(bv, m_type_name, m_ti);
|
||||
@ -212,7 +213,20 @@ namespace chaiscript
|
||||
return m_func->call_match(new_vals);
|
||||
}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
// "this" is not considered part of the arity
|
||||
return m_func->get_arity() - 1;
|
||||
}
|
||||
|
||||
virtual std::string annotation() const
|
||||
{
|
||||
return m_func->annotation();
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
std::vector<Boxed_Value> new_params;
|
||||
chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name));
|
||||
@ -224,17 +238,6 @@ namespace chaiscript
|
||||
return bv;
|
||||
}
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
// "this" is not considered part of the arity
|
||||
return m_func->get_arity() - 1;
|
||||
}
|
||||
|
||||
virtual std::string annotation() const
|
||||
{
|
||||
return m_func->annotation();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_type_name;
|
||||
Proxy_Function m_func;
|
||||
|
@ -65,7 +65,12 @@ namespace chaiscript
|
||||
{
|
||||
public:
|
||||
virtual ~Proxy_Function_Base() {}
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const = 0;
|
||||
Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
Boxed_Value bv = do_call(params);
|
||||
bv.add_dependencies(params.begin(), params.end());
|
||||
return bv;
|
||||
}
|
||||
|
||||
std::vector<Type_Info> get_param_types() const { return m_types; }
|
||||
|
||||
@ -99,6 +104,8 @@ namespace chaiscript
|
||||
virtual std::string annotation() const = 0;
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const = 0;
|
||||
|
||||
Proxy_Function_Base(const std::vector<Type_Info> &t_types)
|
||||
: m_types(t_types)
|
||||
{
|
||||
@ -198,7 +205,19 @@ namespace chaiscript
|
||||
|
||||
virtual ~Dynamic_Proxy_Function() {}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
return m_arity;
|
||||
}
|
||||
|
||||
virtual std::string annotation() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
if (m_arity < 0 || params.size() == size_t(m_arity))
|
||||
{
|
||||
@ -215,16 +234,6 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
return m_arity;
|
||||
}
|
||||
|
||||
virtual std::string annotation() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
private:
|
||||
bool test_guard(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
@ -352,6 +361,12 @@ namespace chaiscript
|
||||
return "";
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
return (*m_f)(build_param_list(params));
|
||||
}
|
||||
|
||||
private:
|
||||
Const_Proxy_Function m_f;
|
||||
std::vector<Boxed_Value> m_args;
|
||||
@ -381,10 +396,6 @@ namespace chaiscript
|
||||
return pimpl != 0;
|
||||
}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
return Do_Call<typename boost::function<Func>::result_type>::go(m_f, params);
|
||||
}
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
@ -407,6 +418,12 @@ namespace chaiscript
|
||||
return "";
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
return Do_Call<typename boost::function<Func>::result_type>::go(m_f, params);
|
||||
}
|
||||
|
||||
private:
|
||||
boost::function<Func> m_f;
|
||||
Func *m_dummy_func;
|
||||
@ -438,23 +455,6 @@ namespace chaiscript
|
||||
}
|
||||
}
|
||||
|
||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
if (params.size() == 1)
|
||||
{
|
||||
const Boxed_Value &bv = params[0];
|
||||
if (bv.is_const())
|
||||
{
|
||||
const Class *o = boxed_cast<const Class *>(bv);
|
||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||
} else {
|
||||
Class *o = boxed_cast<Class *>(bv);
|
||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||
}
|
||||
} else {
|
||||
throw arity_error(params.size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
virtual int get_arity() const
|
||||
{
|
||||
@ -476,6 +476,25 @@ namespace chaiscript
|
||||
return "";
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||
{
|
||||
if (params.size() == 1)
|
||||
{
|
||||
const Boxed_Value &bv = params[0];
|
||||
if (bv.is_const())
|
||||
{
|
||||
const Class *o = boxed_cast<const Class *>(bv);
|
||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||
} else {
|
||||
Class *o = boxed_cast<Class *>(bv);
|
||||
return Handle_Return<typename boost::add_reference<T>::type>::handle(o->*m_attr);
|
||||
}
|
||||
} else {
|
||||
throw arity_error(params.size(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static std::vector<Type_Info> param_types()
|
||||
{
|
||||
|
@ -138,6 +138,7 @@ namespace chaiscript
|
||||
try {
|
||||
if (lhs.is_undef()) {
|
||||
retval = ss.call_function("clone", retval);
|
||||
retval.clear_dependencies();
|
||||
}
|
||||
|
||||
try {
|
||||
|
Loading…
x
Reference in New Issue
Block a user