xo-interpreter: Object->TaggedPtr conversion (prep for primitives)
This commit is contained in:
parent
22670cda3d
commit
4488117ac3
16 changed files with 371 additions and 26 deletions
|
|
@ -7,9 +7,13 @@
|
|||
#include "Integer.hpp"
|
||||
#include "Float.hpp"
|
||||
#include "Boolean.hpp"
|
||||
#include "TaggedPtr.hpp"
|
||||
#include "xo/alloc/Blob.hpp"
|
||||
|
||||
namespace xo {
|
||||
using xo::reflect::Reflect;
|
||||
using xo::reflect::TaggedPtr;
|
||||
using xo::reflect::TypeId;
|
||||
using xo::gc::IAlloc;
|
||||
|
||||
namespace obj {
|
||||
|
|
@ -25,6 +29,34 @@ namespace xo {
|
|||
return Integer::make(mm, *native);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TaggedPtr
|
||||
object_to_int(IAlloc * mm, gp<Object> obj)
|
||||
{
|
||||
/* mm cannot be GC allocator!
|
||||
* That's Object-only
|
||||
*/
|
||||
|
||||
gp<Integer> int_obj = Integer::from(obj);
|
||||
|
||||
if (!int_obj.get()) {
|
||||
throw std::runtime_error(tostr("Object obj found where Integer expected",
|
||||
xtag("obj", obj)));
|
||||
}
|
||||
|
||||
/* allocate a Blob wrapper to satsify GC memory layout demands */
|
||||
|
||||
gp<Blob> tmp = Blob::make(mm, sizeof(T));
|
||||
|
||||
T * p = reinterpret_cast<T *>(tmp->data());
|
||||
|
||||
*p = int_obj->value();
|
||||
|
||||
/* WARNING: retval invalidated when *mm cleared/recycled/collected */
|
||||
|
||||
return Reflect::make_tp(p);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
gp<Object>
|
||||
float_to_object(IAlloc * mm, const TaggedPtr & src)
|
||||
|
|
@ -36,6 +68,34 @@ namespace xo {
|
|||
return Float::make(mm, *native);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
TaggedPtr
|
||||
object_to_float(IAlloc * mm, gp<Object> obj)
|
||||
{
|
||||
/* mm cannot be GC allocator!
|
||||
* That's Object-only
|
||||
*/
|
||||
|
||||
gp<Float> float_obj = Float::from(obj);
|
||||
|
||||
if (!float_obj.get()) {
|
||||
throw std::runtime_error(tostr("Object obj found where Float expected",
|
||||
xtag("obj", obj)));
|
||||
}
|
||||
|
||||
/* allocate a Blob wrapper to satsify GC memory layout demands */
|
||||
|
||||
gp<Blob> tmp = Blob::make(mm, sizeof(T));
|
||||
|
||||
T * p = reinterpret_cast<T *>(tmp->data());
|
||||
|
||||
*p = float_obj->value();
|
||||
|
||||
/* WARNING: retval invalidated when *mm cleared/recycled/collected */
|
||||
|
||||
return Reflect::make_tp(p);
|
||||
}
|
||||
|
||||
gp<Object>
|
||||
bool_to_object(IAlloc * /*mm*/, const TaggedPtr & src)
|
||||
{
|
||||
|
|
@ -45,16 +105,32 @@ namespace xo {
|
|||
|
||||
return Boolean::boolean_obj(*native);
|
||||
}
|
||||
|
||||
TaggedPtr
|
||||
object_to_bool(IAlloc * /*mm*/, gp<Object> obj)
|
||||
{
|
||||
static bool s_true = true;
|
||||
static bool s_false = false;
|
||||
|
||||
gp<Boolean> bool_obj = Boolean::from(obj);
|
||||
|
||||
if (!bool_obj.get()) {
|
||||
throw std::runtime_error(tostr("Object obj found where Boolean expected",
|
||||
xtag("obj", obj)));
|
||||
}
|
||||
|
||||
return Reflect::make_tp(bool_obj->value() ? &s_true : &s_false);
|
||||
}
|
||||
}
|
||||
|
||||
ObjectConverter::ObjectConverter()
|
||||
{
|
||||
this->establish_conversion<std::int32_t>(&int_to_object<std::int32_t>);
|
||||
this->establish_conversion<std::int64_t>(&int_to_object<std::int64_t>);
|
||||
this->establish_conversion<std::int32_t>(&int_to_object<std::int32_t>, &object_to_int<std::int32_t>);
|
||||
this->establish_conversion<std::int64_t>(&int_to_object<std::int64_t>, &object_to_int<std::int64_t>);
|
||||
|
||||
this->establish_conversion<double>(&float_to_object<double>);
|
||||
this->establish_conversion<double>(&float_to_object<double>, &object_to_float<double>);
|
||||
|
||||
this->establish_conversion<bool>(&bool_to_object);
|
||||
this->establish_conversion<bool>(&bool_to_object, &object_to_bool);
|
||||
}
|
||||
|
||||
gp<Object>
|
||||
|
|
@ -69,7 +145,7 @@ namespace xo {
|
|||
return (cvt->cvt_to_object_)(mm, x_tp);
|
||||
} else {
|
||||
if (throw_flag) {
|
||||
throw std::runtime_error(tostr("no object-converter available for instance of type",
|
||||
throw std::runtime_error(tostr("no to-object-converter available for instance of type",
|
||||
xtag("id", x_tp.td()->id()),
|
||||
xtag("name", x_tp.td()->short_name())));
|
||||
}
|
||||
|
|
@ -77,6 +153,23 @@ namespace xo {
|
|||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
TaggedPtr
|
||||
ObjectConverter::tp_from_object(IAlloc * mm, gp<Object> & obj, TypeId target_id, bool throw_flag)
|
||||
{
|
||||
const Converter * cvt = cvt_.lookup(target_id);
|
||||
|
||||
if (cvt) {
|
||||
return (cvt->cvt_from_object_)(mm, obj);
|
||||
} else {
|
||||
if (throw_flag) {
|
||||
throw std::runtime_error(tostr("no from-object-converter available for instance of type",
|
||||
xtag("id", target_id)));
|
||||
}
|
||||
|
||||
return TaggedPtr::universal_null();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue