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;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~Data()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Type_Info m_type_info;
|
Type_Info m_type_info;
|
||||||
boost::any m_obj;
|
boost::any m_obj;
|
||||||
bool m_is_ref;
|
bool m_is_ref;
|
||||||
boost::function<bool (boost::any*)> m_is_null;
|
boost::function<bool (boost::any*)> m_is_null;
|
||||||
|
std::vector<boost::shared_ptr<Data> > m_dependencies;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Object_Data
|
struct Object_Data
|
||||||
@ -245,6 +250,24 @@ namespace chaiscript
|
|||||||
return !is_ref();
|
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:
|
private:
|
||||||
boost::shared_ptr<Data> m_data;
|
boost::shared_ptr<Data> m_data;
|
||||||
|
@ -132,10 +132,6 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Dispatch_Function() {}
|
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
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
@ -167,6 +163,12 @@ namespace chaiscript
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||||
|
{
|
||||||
|
return dispatch(m_funcs.begin(), m_funcs.end(), params);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::pair<std::string, Proxy_Function > > m_funcs;
|
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
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
@ -111,6 +102,16 @@ namespace chaiscript
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
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
|
virtual bool compare_first_type(const Boxed_Value &bv) const
|
||||||
{
|
{
|
||||||
return dynamic_object_typename_match(bv, m_type_name, m_ti);
|
return dynamic_object_typename_match(bv, m_type_name, m_ti);
|
||||||
@ -212,17 +213,6 @@ namespace chaiscript
|
|||||||
return m_func->call_match(new_vals);
|
return m_func->call_match(new_vals);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Boxed_Value operator()(const std::vector<Boxed_Value> ¶ms) const
|
|
||||||
{
|
|
||||||
std::vector<Boxed_Value> new_params;
|
|
||||||
chaiscript::Boxed_Value bv = var(Dynamic_Object(m_type_name));
|
|
||||||
new_params.push_back(bv);
|
|
||||||
new_params.insert(new_params.end(), params.begin(), params.end());
|
|
||||||
|
|
||||||
(*m_func)(new_params);
|
|
||||||
|
|
||||||
return bv;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual int get_arity() const
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
@ -235,6 +225,19 @@ namespace chaiscript
|
|||||||
return m_func->annotation();
|
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));
|
||||||
|
new_params.push_back(bv);
|
||||||
|
new_params.insert(new_params.end(), params.begin(), params.end());
|
||||||
|
|
||||||
|
(*m_func)(new_params);
|
||||||
|
|
||||||
|
return bv;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string m_type_name;
|
std::string m_type_name;
|
||||||
Proxy_Function m_func;
|
Proxy_Function m_func;
|
||||||
|
@ -65,7 +65,12 @@ namespace chaiscript
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Proxy_Function_Base() {}
|
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; }
|
std::vector<Type_Info> get_param_types() const { return m_types; }
|
||||||
|
|
||||||
@ -99,6 +104,8 @@ namespace chaiscript
|
|||||||
virtual std::string annotation() const = 0;
|
virtual std::string annotation() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const = 0;
|
||||||
|
|
||||||
Proxy_Function_Base(const std::vector<Type_Info> &t_types)
|
Proxy_Function_Base(const std::vector<Type_Info> &t_types)
|
||||||
: m_types(t_types)
|
: m_types(t_types)
|
||||||
{
|
{
|
||||||
@ -198,7 +205,19 @@ namespace chaiscript
|
|||||||
|
|
||||||
virtual ~Dynamic_Proxy_Function() {}
|
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))
|
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:
|
private:
|
||||||
bool test_guard(const std::vector<Boxed_Value> ¶ms) const
|
bool test_guard(const std::vector<Boxed_Value> ¶ms) const
|
||||||
{
|
{
|
||||||
@ -352,6 +361,12 @@ namespace chaiscript
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual Boxed_Value do_call(const std::vector<Boxed_Value> ¶ms) const
|
||||||
|
{
|
||||||
|
return (*m_f)(build_param_list(params));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Const_Proxy_Function m_f;
|
Const_Proxy_Function m_f;
|
||||||
std::vector<Boxed_Value> m_args;
|
std::vector<Boxed_Value> m_args;
|
||||||
@ -381,10 +396,6 @@ namespace chaiscript
|
|||||||
return pimpl != 0;
|
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
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
@ -407,6 +418,12 @@ namespace chaiscript
|
|||||||
return "";
|
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:
|
private:
|
||||||
boost::function<Func> m_f;
|
boost::function<Func> m_f;
|
||||||
Func *m_dummy_func;
|
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
|
virtual int get_arity() const
|
||||||
{
|
{
|
||||||
@ -476,6 +476,25 @@ namespace chaiscript
|
|||||||
return "";
|
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:
|
private:
|
||||||
static std::vector<Type_Info> param_types()
|
static std::vector<Type_Info> param_types()
|
||||||
{
|
{
|
||||||
|
@ -138,6 +138,7 @@ namespace chaiscript
|
|||||||
try {
|
try {
|
||||||
if (lhs.is_undef()) {
|
if (lhs.is_undef()) {
|
||||||
retval = ss.call_function("clone", retval);
|
retval = ss.call_function("clone", retval);
|
||||||
|
retval.clear_dependencies();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user