python-on-a-chip online compiler

Dependencies:   mbed TSI

/media/uploads/va009039/p14p-f446re.png

more info: python-on-a-chip

platform/mbed/NativeClassInterface.h

Committer:
va009039
Date:
2013-03-13
Revision:
3:559c4bd38111
Parent:
2:a2bea117e22e

File content as of revision 3:559c4bd38111:

// NativeClassInterface.h 2013/3/13
#pragma once
#include <stdarg.h>
class NativeClassInterface {
public:
    template<class T>
    PmReturn_t init()
    {
        PmReturn_t retval = check_argv_type(0);
        PM_RETURN_IF_ERROR(retval);
        T* obj = new T();
        return _save_obj<T>(obj);
    }

    template<class T, typename A1>
    PmReturn_t init(PmType_t a1_type)
    {
        PmReturn_t retval = check_argv_type(1, a1_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj = new T(argv<A1>(1));
        return _save_obj<T>(obj);
    }

    template<class T, typename A1, typename A2>
    PmReturn_t init(PmType_t a1_type, PmType_t a2_type)
    {
        PmReturn_t retval = check_argv_type(2, a1_type, a2_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj = new T(argv<A1>(1), argv<A2>(2));
        return _save_obj<T>(obj);
    }

    template<class T, typename A1, typename A2, typename A3>
    PmReturn_t init(PmType_t a1_type, PmType_t a2_type, PmType_t a3_type)
    {
        PmReturn_t retval = check_argv_type(3, a1_type, a2_type, a3_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj = new T(argv<A1>(1), argv<A2>(2), argv<A3>(3));
        return _save_obj<T>(obj);
    }

    template<class T, void(T::*member)()>
    PmReturn_t method(PmType_t ret_type)
    {
        PmReturn_t retval = check_argv_type(0);
        PM_RETURN_IF_ERROR(retval);
        T* obj;
        retval = _load_obj<T>(&obj);
        PM_RETURN_IF_ERROR(retval);
        (obj->*member)();
        NATIVE_SET_TOS(PM_NONE);
        return retval;
    }

    template<class T, typename A1, void(T::*member)(A1)>
    PmReturn_t method(PmType_t ret_type, PmType_t a1_type)
    {
        PmReturn_t retval = check_argv_type(1, a1_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj;
        retval = _load_obj<T>(&obj);
        PM_RETURN_IF_ERROR(retval);
        (obj->*member)(argv<A1>(1));
        NATIVE_SET_TOS(PM_NONE);
        return retval;
    }

    template<class T, typename A1, typename A2, void(T::*member)(A1,A2)>
    PmReturn_t method(PmType_t ret_type, PmType_t a1_type, PmType_t a2_type)
    {
        PmReturn_t retval = check_argv_type(2, a1_type, a2_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj;
        retval = _load_obj<T>(&obj);
        PM_RETURN_IF_ERROR(retval);
        (obj->*member)(argv<A1>(1), argv<A2>(2));
        NATIVE_SET_TOS(PM_NONE);
        return retval;
    }

    template<typename R, class T, R(T::*member)()>
    PmReturn_t method(PmType_t ret_type)
    {
        PmReturn_t retval = check_argv_type(0);
        PM_RETURN_IF_ERROR(retval);
        T* obj;
        retval = _load_obj<T>(&obj);
        PM_RETURN_IF_ERROR(retval);
        R value = (obj->*member)();
        return set_return_value<R>(ret_type, value);
    }

    template<typename R, class T, typename A1, R(T::*member)(A1)>
    PmReturn_t method(PmType_t ret_type, PmType_t a1_type)
    {
        PmReturn_t retval = check_argv_type(1, a1_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj;
        retval = _load_obj<T>(&obj);
        PM_RETURN_IF_ERROR(retval);
        R value = (obj->*member)(argv<A1>(1));
        return set_return_value<R>(ret_type, value);
    }

    template<typename R, class T, typename A1, typename A2, typename A3, typename A4, R(T::*member)(A1, A2, A3, A4)>
    PmReturn_t method(PmType_t ret_type, PmType_t a1_type, PmType_t a2_type, PmType_t a3_type, PmType_t a4_type)
    {
        PmReturn_t retval = check_argv_type(4, a1_type, a2_type, a3_type, a4_type);
        PM_RETURN_IF_ERROR(retval);
        T* obj;
        retval = _load_obj<T>(&obj);
        PM_RETURN_IF_ERROR(retval);
        R value = (obj->*member)(argv<A1>(1), argv<A2>(2), argv<A3>(3), argv<A4>(4));
        return set_return_value<R>(ret_type, value);
    }

    PmReturn_t check_argv_type(int arg_n, ...);
    
    template<class T>
    PmReturn_t _save_obj(T* obj)
    {
        PmReturn_t retval = PM_RET_OK;
        pPmObj_t pself = NATIVE_GET_LOCAL(0);
        pPmObj_t pattrs = (pPmObj_t)((pPmInstance_t)pself)->cli_attrs;
        pPmObj_t pn;
        retval = int_new((uint32_t)obj, &pn);
        PM_RETURN_IF_ERROR(retval);
        uint8_t objid;
        heap_gcPushTempRoot(pn, &objid);
        retval = dict_setItem(pattrs, PM_NONE, pn);
        heap_gcPopTempRoot(objid);
        PM_RETURN_IF_ERROR(retval);
        NATIVE_SET_TOS(PM_NONE);
        return retval;
    }

    template<class T>
    PmReturn_t _load_obj(T** obj)
    {
        PmReturn_t retval = PM_RET_OK;
        pPmObj_t pself = NATIVE_GET_LOCAL(0);
        pPmObj_t pattrs = reinterpret_cast<pPmObj_t>(((pPmInstance_t)pself)->cli_attrs);
        pPmObj_t pn;
        retval = dict_getItem(pattrs, PM_NONE, &pn);
        PM_RETURN_IF_ERROR(retval);
        *obj = reinterpret_cast<T*>(((pPmInt_t)pn)->val);
        return retval;
    }

    template<typename R>
    PmReturn_t set_return_value(PmType_t ret_type, R value);

    template<typename A>
    A argv(int n);
};