reactor-c
C Runtime for Lingua Franca
Loading...
Searching...
No Matches
pythontarget.h File Reference
#include <Python.h>
#include <structmember.h>
#include <limits.h>
#include "python_tag.h"
#include "python_port.h"
#include "python_action.h"

Go to the source code of this file.

Macros

#define PY_SSIZE_T_CLEAN
 
#define CONCAT(x, y)
 
#define GEN_NAME(x, y)
 
#define STRINGIFY(X)
 
#define TOSTRING(x)
 

Functions

PyObject * py_schedule (PyObject *self, PyObject *args)
 
PyObject * py_schedule_copy (PyObject *self, PyObject *args)
 
PyObject * py_request_stop (PyObject *self, PyObject *args)
 
PyObject * py_source_directory (PyObject *self, PyObject *args)
 Return the source directory path (where the main .lf file is) as a string.
 
PyObject * py_package_directory (PyObject *self, PyObject *args)
 Return the root project directory path as a string.
 
PyObject * py_main (PyObject *self, PyObject *args)
 
PyObject * convert_C_port_to_py (void *port, int width)
 
PyObject * convert_C_action_to_py (void *action)
 
PyObject * get_python_function (string module, string class, int instance_id, string func)
 
PyObject * load_serializer (string package_name)
 
PyObject * custom_serialize (PyObject *obj, PyObject *custom_serializer)
 
PyObject * custom_deserialize (PyObject *serialized_pyobject, PyObject *custom_serializer)
 
PyMODINIT_FUNC GEN_NAME (PyInit_, MODULE_NAME)(void)
 

Variables

PyObject * globalPythonModule
 
PyObject * globalPythonModuleDict
 
PyObject * global_pickler
 
environment_ttop_level_environment
 

Detailed Description

Author
Edward A. Lee (eal@b.nosp@m.erke.nosp@m.ley.e.nosp@m.du)
Soroush Bateni (sorou.nosp@m.sh@u.nosp@m.tdall.nosp@m.as.e.nosp@m.du)
Hou Seng Wong (house.nosp@m.ngw@.nosp@m.berke.nosp@m.ley..nosp@m.edu)

LICENSE

Copyright (c) 2020, The University of California at Berkeley. Copyright (c) 2021, The University of Texas at Dallas.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

DESCRIPTION

Target-specific runtime functions for the Python target language. This API layer can be used in conjunction with: target Python;

Note for target language developers. This is one way of developing a target language where the C core runtime is adopted. This file is a translation layer that implements Lingua Franca APIs which interact with the lf_set and lf_schedule APIs. This file can act as a template for future runtime developement for target languages. For source generation, see xtext/org.icyphy.linguafranca/src/org/icyphy/generator/PythonGenerator.xtend.

Macro Definition Documentation

◆ CONCAT

#define CONCAT ( x,
y )
Value:
x##y

◆ GEN_NAME

#define GEN_NAME ( x,
y )
Value:
CONCAT(x, y)
#define CONCAT(x, y)
Definition pythontarget.h:66

◆ PY_SSIZE_T_CLEAN

#define PY_SSIZE_T_CLEAN

◆ STRINGIFY

#define STRINGIFY ( X)
Value:
#X

◆ TOSTRING

#define TOSTRING ( x)
Value:
#define STRINGIFY(X)
Definition pythontarget.h:68

Function Documentation

◆ convert_C_action_to_py()

PyObject * convert_C_action_to_py ( void * action)

A helper function to convert C actions to Python action capsules

See also
xtext/org.icyphy.linguafranca/src/org/icyphy/generator/CGenerator.xtend for details about C actions Python actions have the following fields (for more information
generic_action_capsule_struct): PyObject_HEAD PyObject* action; PyObject* value; bool is_present;

The input to this function is a pointer to a C action, which might or might not contain a value and an is_present field. To simplify the assumptions made by this function, the "value" and "is_present" are passed to the function instead of expecting them to exist.

The void* pointer to the C action instance is encapsulated in a PyCapsule instead of passing an exposed pointer through Python.

See also
https://docs.python.org/3/c-api/capsule.html This encapsulation is done by calling PyCapsule_New(action, "name_of_the_container_in_the_capsule", NULL), where "name_of_the_container_in_the_capsule" is an agreed-upon container name inside the capsule. This capsule can then be treated as a PyObject* and safely passed through Python code. On the other end (which is in schedule functions), PyCapsule_GetPointer(recieved_action,"action") can be called to retrieve the void* pointer into recieved_action.

A helper function to convert C actions to Python action capsules

See also
xtext/org.icyphy.linguafranca/src/org/icyphy/generator/CGenerator.xtend for details about C actions Python actions have the following fields (for more informatino
generic_action_capsule_struct): PyObject_HEAD PyObject* action; PyObject* value; bool is_present;

The input to this function is a pointer to a C action, which might or might not contain a value and an is_present field. To simplify the assumptions made by this function, the "value" and "is_present" are passed to the function instead of expecting them to exist.

The void* pointer to the C action instance is encapsulated in a PyCapsule instead of passing an exposed pointer through Python.

See also
https://docs.python.org/3/c-api/capsule.html This encapsulation is done by calling PyCapsule_New(action, "name_of_the_container_in_the_capsule", NULL), where "name_of_the_container_in_the_capsule" is an agreed-upon container name inside the capsule. This capsule can then be treated as a PyObject* and safely passed through Python code. On the other end (which is in schedule functions), PyCapsule_GetPointer(received_action,"action") can be called to retrieve the void* pointer into received_action.

◆ convert_C_port_to_py()

PyObject * convert_C_port_to_py ( void * port,
int width )

A function that is called any time a Python reaction is called with ports as inputs and outputs. This function converts ports that are either a multiport or a non-multiport into a port_capsule.

First, the void* pointer is stored in a PyCapsule. If the port is not a multiport, the value and is_present fields are copied verbatim. These feilds then can be accessed from the Python code as port.value and port.is_present. If the value is absent, it will be set to None.

For multiports, the value of the port_capsule (i.e., port.value) is always set to None and is_present is set to false. Individual ports can then later be accessed in Python code as port[idx].

◆ custom_deserialize()

PyObject * custom_deserialize ( PyObject * serialized_pyobject,
PyObject * custom_serializer )

Deserialize Python object from a bytes object using external serializer

Parameters
serialized_pyobjectThe serialized bytes Python object
custom_serializerThe custom Serializer class
Returns
Deserialized Python object

◆ custom_serialize()

PyObject * custom_serialize ( PyObject * obj,
PyObject * custom_serializer )

Serialize Python object to a bytes object using external serializer

Parameters
objThe Python object to serialize
custom_serializerThe custom Serializer class
Returns
Serialized Python bytes object

◆ GEN_NAME()

PyMODINIT_FUNC GEN_NAME ( PyInit_ ,
MODULE_NAME  )

◆ get_python_function()

PyObject * get_python_function ( string module,
string class,
int instance_id,
string func )

Invoke a Python func in class[instance_id] from module. Class instances in generated Python code are always instantiated in a list of template classs[_class(params), _class(params), ...] (note the extra s) regardless of whether a bank is used or not. If there is no bank, or a bank of width 1, the list will be instantiated as classs[_class(params)].

This function would thus call classs[0] to access the first instance in a bank and so on.

Possible optimizations include: - Not loading the module each time (by storing it in global memory),

  • Keeping a persistent argument table
    Parameters
    moduleThe Python module to load the function from. In embedded mode, it should be set to "__main__"
    classThe name of the list of classes in the generated Python code
    instance_idThe element number in the list of classes. class[instance_id] points to a class instance
    funcThe reaction functino to be called
    pArgsthe PyList of arguments to be sent to function func()
    Invoke a Python func in class[instance_id] from module. Class instances in generated Python code are always instantiated in a list of template classs[_class(params), _class(params), ...] (note the extra s) regardless of whether a bank is used or not. If there is no bank, or a bank of width 1, the list will be instantiated as classs[_class(params)].

This function would thus call classs[0] to access the first instance in a bank and so on.

Possible optimizations include: - Not loading the module each time (by storing it in global memory),

  • Keeping a persistent argument table
    Parameters
    moduleThe Python module to load the function from. In embedded mode, it should be set to "__main__"
    classThe name of the list of classes in the generated Python code
    instance_idThe element number in the list of classes. class[instance_id] points to a class instance
    funcThe reaction functino to be called
    pArgsthe PyList of arguments to be sent to function func()
    Returns
    The function or NULL on error.

◆ load_serializer()

PyObject * load_serializer ( string package_name)

Load the Serializer class from package name

Parameters
package_nameName of the python package to load
Returns
Initialized Serializer class

◆ py_main()

PyObject * py_main ( PyObject * self,
PyObject * py_args )

The main function of this Python module.

Parameters
py_argsA single object, which should be a list of arguments taken from sys.argv().

◆ py_package_directory()

PyObject * py_package_directory ( PyObject * self,
PyObject * args )

Return the root project directory path as a string.

Parameters
selfThe lf object.
argsEmpty.
Returns
PyObject* A Python string.

◆ py_request_stop()

PyObject * py_request_stop ( PyObject * self,
PyObject * args )

Stop execution at the conclusion of the current logical time.

◆ py_schedule()

PyObject * py_schedule ( PyObject * self,
PyObject * args )

Schedule an action to occur with the specified value and time offset with no payload (no value conveyed). See schedule_token(), which this uses, for details.

Parameters
selfPointer to the calling object.
argscontains:
  • action: Pointer to an action on the self struct.
  • offset: The time offset over and above that in the action.

Schedule an action to occur with the specified time offset with no payload (no value conveyed). This function is callable in Python by calling action_name.schedule(offset). Some examples include: action_name.schedule(5) action_name.schedule(NSEC(5)) See schedule_token(), which this uses, for details.

Parameters
selfPointer to the calling object.
argscontains:
  • action: Pointer to an action on the self struct.
  • offset: The time offset over and above that in the action.

◆ py_schedule_copy()

PyObject * py_schedule_copy ( PyObject * self,
PyObject * args )

Schedule an action to occur with the specified value and time offset with a copy of the specified value. See reactor.h for documentation.

◆ py_source_directory()

PyObject * py_source_directory ( PyObject * self,
PyObject * args )

Return the source directory path (where the main .lf file is) as a string.

Parameters
selfThe lf object.
argsEmpty.
Returns
PyObject* A Python string.

Variable Documentation

◆ global_pickler

PyObject* global_pickler
extern

◆ globalPythonModule

PyObject* globalPythonModule
extern

◆ globalPythonModuleDict

PyObject* globalPythonModuleDict
extern

◆ top_level_environment

environment_t* top_level_environment
extern