Guest User

Untitled

a guest
Oct 1st, 2010
241
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 102.34 KB | None | 0 0
  1.  
  2. // Generated code for Python source for module '__main__'
  3.  
  4. // This code is in part copyright Kay Hayen, license GPLv3. This has the consequence that
  5. // your must either obtain a commercial license or also publish your original source code
  6. // under the same license unless you don't distribute this source or its binary.
  7.  
  8. #ifdef __NUITKA_NO_ASSERT__
  9. #define NDEBUG
  10. #endif
  11.  
  12. // Include the Python C/API header files
  13.  
  14. #include "Python.h"
  15. #include "methodobject.h"
  16. #include "frameobject.h"
  17. #include <stdio.h>
  18. #include <string>
  19.  
  20. // An idea I first saw used with Cython, hint the compiler about branches that are more or
  21. // less likely to be taken. And hint the compiler about things that we assume to be
  22. // normally true. If other compilers can do similar, I would be grateful for howtos.
  23.  
  24. #ifdef __GNUC__
  25. #define likely(x) __builtin_expect(!!(x), 1)
  26. #define unlikely(x) __builtin_expect(!!(x), 0)
  27. #else
  28. #define likely(x) (x)
  29. #define unlikely(x) (x)
  30. #endif
  31.  
  32. // An idea to reduce the amount of exported symbols, esp. as we are using C++ and classes
  33. // do not allow to limit their visibility normally.
  34. #ifdef __GNUC__
  35. #define NUITKA_MODULE_INIT_FUNCTION PyMODINIT_FUNC __attribute__((visibility( "default" )))
  36. #else
  37. #define NUITKA_MODULE_INIT_FUNCTION PyMODINIT_FUNC
  38. #endif
  39.  
  40. static PyObject *_expression_temps[100];
  41. static PyObject *_eval_globals_tmp;
  42. static PyObject *_eval_locals_tmp;
  43.  
  44. // From CPython, to allow us quick access to the dictionary of an module.
  45. typedef struct {
  46.         PyObject_HEAD
  47.         PyObject *md_dict;
  48. } PyModuleObject;
  49.  
  50.  
  51.  
  52. // We unstream some constant objects using the "cPickle" module function "loads"
  53. static PyObject *_module_cPickle = NULL;
  54. static PyObject *_module_cPickle_function_loads = NULL;
  55.  
  56. // Sentinel PyObject to be used for all our call iterator endings. It will become
  57. // a PyCObject pointing to NULL. TODO: Hopefully that is unique enough.
  58. static PyObject *_sentinel_value = NULL;
  59.  
  60. static PyObject *_python_bool_False = NULL;
  61. static PyObject *_python_bool_True = NULL;
  62. static PyObject *_python_dict_empty = NULL;
  63. static PyObject *_python_int_0 = NULL;
  64. static PyObject *_python_int_pos_1 = NULL;
  65. static PyObject *_python_int_pos_2 = NULL;
  66. static PyObject *_python_str_angle_hello__genexpr = NULL;
  67. static PyObject *_python_str_angle_module = NULL;
  68. static PyObject *_python_str_digest_8d35108ffe2ad173a697734a3e9938e1 = NULL;
  69. static PyObject *_python_str_empty = NULL;
  70. static PyObject *_python_str_plain___doc__ = NULL;
  71. static PyObject *_python_str_plain___file__ = NULL;
  72. static PyObject *_python_str_plain___module__ = NULL;
  73. static PyObject *_python_str_plain_all = NULL;
  74. static PyObject *_python_str_plain_hello__genexpr = NULL;
  75. static PyObject *_python_str_plain_i = NULL;
  76. static PyObject *_python_str_plain_int = NULL;
  77. static PyObject *_python_str_plain_math = NULL;
  78. static PyObject *_python_str_plain_num_primes = NULL;
  79. static PyObject *_python_str_plain_sqrt = NULL;
  80. static PyObject *_python_str_plain_xrange = NULL;
  81. static PyObject *_python_tuple_empty = NULL;
  82. static PyObject *_python_tuple_int_pos_2_int_pos_500000 = NULL;
  83.  
  84. static PyObject *_unstreamConstant( char const *buffer, int size )
  85. {
  86.     PyObject *temp = PyString_FromStringAndSize( buffer, size );
  87.  
  88.     PyObject *result = PyObject_CallFunctionObjArgs( _module_cPickle_function_loads, temp, NULL );
  89.     assert( result );
  90.  
  91.     Py_DECREF( temp );
  92.  
  93.     return result;
  94. }
  95.  
  96. static PyModuleObject *_module_builtin = NULL;
  97.  
  98. static int _initConstants()
  99. {
  100.     if ( _sentinel_value == NULL )
  101.     {
  102.         _sentinel_value = PyCObject_FromVoidPtr( NULL, NULL );
  103.         assert( _sentinel_value );
  104.  
  105.         _module_builtin = (PyModuleObject *)PyImport_ImportModule( "__builtin__" );
  106.         assert( _module_builtin );
  107.  
  108.         _module_cPickle = PyImport_ImportModule( "cPickle" );
  109.         assert( _module_cPickle );
  110.         _module_cPickle_function_loads = PyObject_GetAttrString( _module_cPickle, "loads" );
  111.         assert( _module_cPickle_function_loads );
  112.  
  113.         _python_bool_False = _unstreamConstant( R"raw(I00)raw" "\n" R"raw(.)raw", 5 );
  114.         _python_bool_True = _unstreamConstant( R"raw(I01)raw" "\n" R"raw(.)raw", 5 );
  115.         _python_dict_empty = _unstreamConstant( R"raw((dp1)raw" "\n" R"raw(.)raw", 6 );
  116.         _python_int_0 = PyInt_FromLong( 0 );
  117.         _python_int_pos_1 = PyInt_FromLong( 1 );
  118.         _python_int_pos_2 = PyInt_FromLong( 2 );
  119.         _python_str_angle_hello__genexpr = PyString_FromStringAndSize( R"raw(<hello__genexpr>)raw", 16 );
  120.         assert( PyString_Size( _python_str_angle_hello__genexpr ) == 16 );
  121.         _python_str_angle_module = PyString_FromStringAndSize( R"raw(<module>)raw", 8 );
  122.         assert( PyString_Size( _python_str_angle_module ) == 8 );
  123.         _python_str_digest_8d35108ffe2ad173a697734a3e9938e1 = PyString_FromStringAndSize( R"raw(hello.py)raw", 8 );
  124.         assert( PyString_Size( _python_str_digest_8d35108ffe2ad173a697734a3e9938e1 ) == 8 );
  125.         _python_str_empty = PyString_FromStringAndSize( R"raw()raw", 0 );
  126.         assert( PyString_Size( _python_str_empty ) == 0 );
  127.         _python_str_plain___doc__ = PyString_FromStringAndSize( R"raw(__doc__)raw", 7 );
  128.         assert( PyString_Size( _python_str_plain___doc__ ) == 7 );
  129.         _python_str_plain___file__ = PyString_FromStringAndSize( R"raw(__file__)raw", 8 );
  130.         assert( PyString_Size( _python_str_plain___file__ ) == 8 );
  131.         _python_str_plain___module__ = PyString_FromStringAndSize( R"raw(__module__)raw", 10 );
  132.         assert( PyString_Size( _python_str_plain___module__ ) == 10 );
  133.         _python_str_plain_all = PyString_FromStringAndSize( R"raw(all)raw", 3 );
  134.         assert( PyString_Size( _python_str_plain_all ) == 3 );
  135.         _python_str_plain_hello__genexpr = PyString_FromStringAndSize( R"raw(hello__genexpr)raw", 14 );
  136.         assert( PyString_Size( _python_str_plain_hello__genexpr ) == 14 );
  137.         _python_str_plain_i = PyString_FromStringAndSize( R"raw(i)raw", 1 );
  138.         assert( PyString_Size( _python_str_plain_i ) == 1 );
  139.         _python_str_plain_int = PyString_FromStringAndSize( R"raw(int)raw", 3 );
  140.         assert( PyString_Size( _python_str_plain_int ) == 3 );
  141.         _python_str_plain_math = PyString_FromStringAndSize( R"raw(math)raw", 4 );
  142.         assert( PyString_Size( _python_str_plain_math ) == 4 );
  143.         _python_str_plain_num_primes = PyString_FromStringAndSize( R"raw(num_primes)raw", 10 );
  144.         assert( PyString_Size( _python_str_plain_num_primes ) == 10 );
  145.         _python_str_plain_sqrt = PyString_FromStringAndSize( R"raw(sqrt)raw", 4 );
  146.         assert( PyString_Size( _python_str_plain_sqrt ) == 4 );
  147.         _python_str_plain_xrange = PyString_FromStringAndSize( R"raw(xrange)raw", 6 );
  148.         assert( PyString_Size( _python_str_plain_xrange ) == 6 );
  149.         _python_tuple_empty = _unstreamConstant( R"raw((t.)raw", 3 );
  150.         _python_tuple_int_pos_2_int_pos_500000 = _unstreamConstant( R"raw((I2)raw" "\n" R"raw(I500000)raw" "\n" R"raw(tp1)raw" "\n" R"raw(.)raw", 17 );
  151.     }
  152. }
  153.  
  154. template<typename... P>
  155. static void PRINT_ITEMS( bool new_line, PyObject *file, P...eles );
  156. static PyObject *INCREASE_REFCOUNT( PyObject *object );
  157.  
  158. static int _current_line = -1;
  159. static char *_current_file = NULL;
  160.  
  161. class _PythonException
  162. {
  163.     public:
  164.         _PythonException()
  165.         {
  166.             this->line = _current_line;
  167.  
  168.             this->_importFromPython();
  169.         }
  170.  
  171.         _PythonException( PyObject *exception )
  172.         {
  173.             assert( exception );
  174.             assert( exception->ob_refcnt > 0 );
  175.  
  176.             this->line = _current_line;
  177.  
  178.             Py_INCREF( exception );
  179.  
  180.             this->exception_type = exception;
  181.             this->exception_value = NULL;
  182.             this->exception_tb = NULL;
  183.         }
  184.  
  185.         _PythonException( PyObject *exception, PyTracebackObject *traceback )
  186.         {
  187.             assert( exception );
  188.             assert( exception->ob_refcnt > 0 );
  189.  
  190.             assert( traceback );
  191.             assert( traceback->ob_refcnt > 0 );
  192.  
  193.             this->line = _current_line;
  194.  
  195.             this->exception_type = exception;
  196.             this->exception_value = NULL;
  197.             this->exception_tb = (PyObject *)traceback;
  198.         }
  199.  
  200.         _PythonException( PyObject *exception, PyObject *value, float unused )
  201.         {
  202.             assert( exception );
  203.             assert( value );
  204.             assert( exception->ob_refcnt > 0 );
  205.             assert( value->ob_refcnt > 0 );
  206.  
  207.             this->line = _current_line;
  208.  
  209.             Py_INCREF( exception );
  210.             Py_INCREF( value );
  211.  
  212.             this->exception_type = exception;
  213.             this->exception_value = value;
  214.             this->exception_tb = NULL;
  215.         }
  216.  
  217.         _PythonException( PyObject *exception, PyObject *value, PyTracebackObject *traceback )
  218.         {
  219.             assert( exception );
  220.             assert( value );
  221.             assert( traceback );
  222.             assert( exception->ob_refcnt > 0 );
  223.             assert( value->ob_refcnt > 0 );
  224.             assert( traceback->ob_refcnt > 0 );
  225.  
  226.             this->line = _current_line;
  227.  
  228.             this->exception_type = exception;
  229.             this->exception_value = value;
  230.             this->exception_tb = (PyObject *)traceback;
  231.         }
  232.  
  233.         _PythonException( const _PythonException &other )
  234.         {
  235.             this->line            = other.line;
  236.  
  237.             this->exception_type  = other.exception_type;
  238.             this->exception_value = other.exception_value;
  239.             this->exception_tb    = other.exception_tb;
  240.  
  241.             Py_XINCREF( this->exception_type );
  242.             Py_XINCREF( this->exception_value );
  243.             Py_XINCREF( this->exception_tb );
  244.         }
  245.  
  246.         void operator=( const _PythonException &other )
  247.         {
  248.             Py_XINCREF( other.exception_type );
  249.             Py_XINCREF( other.exception_value );
  250.             Py_XINCREF( other.exception_tb );
  251.  
  252.             Py_XDECREF( this->exception_type );
  253.             Py_XDECREF( this->exception_value );
  254.             Py_XDECREF( this->exception_tb );
  255.  
  256.             this->line            = other.line;
  257.  
  258.             this->exception_type  = other.exception_type;
  259.             this->exception_value = other.exception_value;
  260.             this->exception_tb    = other.exception_tb;
  261.  
  262.         }
  263.  
  264.         ~_PythonException()
  265.         {
  266.             Py_XDECREF( this->exception_type );
  267.             Py_XDECREF( this->exception_value );
  268.             Py_XDECREF( this->exception_tb );
  269.         }
  270.  
  271.         inline void _importFromPython()
  272.         {
  273.  
  274.             PyErr_Fetch( &this->exception_type, &this->exception_value, &this->exception_tb );
  275.             assert( this->exception_type );
  276.  
  277.             // PyErr_NormalizeException( &this->exception_type, &this->exception_value, &this->exception_tb );
  278.             PyErr_Clear();
  279.         }
  280.  
  281.         inline int getLine() const
  282.         {
  283.             return this->line;
  284.         }
  285.  
  286.         inline bool matches( PyObject *exception ) const
  287.         {
  288.             return PyErr_GivenExceptionMatches( this->exception_type, exception ) || PyErr_GivenExceptionMatches( this->exception_value, exception );;
  289.         }
  290.  
  291.         inline void toPython()
  292.         {
  293.             PyErr_Restore( this->exception_type, this->exception_value, this->exception_tb );
  294.  
  295.             PyThreadState *thread_state = PyThreadState_GET();
  296.  
  297.             assert( this->exception_type == thread_state->curexc_type );
  298.             assert( thread_state->curexc_type );
  299.  
  300.             this->exception_type  = NULL;
  301.             this->exception_value = NULL;
  302.             this->exception_tb    = NULL;
  303.         }
  304.  
  305.         inline void toExceptionHandler()
  306.         {
  307.             // Restore only sets the current exception to the interpreter.
  308.             PyThreadState *thread_state = PyThreadState_GET();
  309.  
  310.             PyObject *old_type  = thread_state->exc_type;
  311.             PyObject *old_value = thread_state->exc_value;
  312.             PyObject *old_tb    = thread_state->exc_traceback;
  313.  
  314.             thread_state->exc_type = this->exception_type;
  315.             thread_state->exc_value = this->exception_value;
  316.             thread_state->exc_traceback = this->exception_tb;
  317.  
  318.             Py_INCREF(  thread_state->exc_type );
  319.             Py_XINCREF( thread_state->exc_value );
  320.             Py_XINCREF(  thread_state->exc_traceback );
  321.  
  322.             Py_XDECREF( old_type );
  323.             Py_XDECREF( old_value );
  324.             Py_XDECREF( old_tb );
  325.  
  326.             PySys_SetObject( (char *)"exc_type", thread_state->exc_type );
  327.             PySys_SetObject( (char *)"exc_value", thread_state->exc_value );
  328.             PySys_SetObject( (char *)"exc_traceback", thread_state->exc_traceback );
  329.         }
  330.  
  331.         inline PyObject *getType()
  332.         {
  333.             if ( this->exception_value == NULL )
  334.             {
  335.                 PyErr_NormalizeException( &this->exception_type, &this->exception_value, &this->exception_tb );
  336.             }
  337.  
  338.             return this->exception_type;
  339.         }
  340.  
  341.         inline PyObject *getTraceback() const
  342.         {
  343.             return this->exception_tb;
  344.         }
  345.  
  346.         inline PyObject *setTraceback( PyTracebackObject *traceback )
  347.         {
  348.             assert( traceback );
  349.             assert( traceback->ob_refcnt > 0 );
  350.  
  351.             // printf( "setTraceback %d\n", traceback->ob_refcnt );
  352.  
  353.             // Py_INCREF( traceback );
  354.             this->exception_tb = (PyObject *)traceback;
  355.         }
  356.  
  357.         inline bool hasTraceback() const
  358.         {
  359.             return this->exception_tb != NULL;
  360.         }
  361.  
  362.         void setType( PyObject *exception_type )
  363.         {
  364.             Py_XDECREF( this->exception_type );
  365.             this->exception_type = exception_type;
  366.         }
  367.  
  368.         inline PyObject *getObject()
  369.         {
  370.             PyErr_NormalizeException( &this->exception_type, &this->exception_value, &this->exception_tb );
  371.  
  372.             return this->exception_value;
  373.         }
  374.  
  375.         void dump() const
  376.         {
  377.             PRINT_ITEMS( true, NULL, this->exception_type );
  378.         }
  379.  
  380.  
  381.     protected:
  382.         PyObject *exception_type, *exception_value, *exception_tb;
  383.         int line;
  384. };
  385.  
  386. class _PythonExceptionKeeper
  387. {
  388.     public:
  389.         _PythonExceptionKeeper()
  390.         {
  391.             empty = true;
  392.         }
  393.  
  394.         ~_PythonExceptionKeeper()
  395.         {
  396.             if ( this->empty == false)
  397.             {
  398.                 delete this->saved;
  399.             }
  400.         }
  401.  
  402.         void save( const _PythonException &e )
  403.         {
  404.             this->saved = new _PythonException( e );
  405.  
  406.             empty = false;
  407.         }
  408.  
  409.         void rethrow()
  410.         {
  411.             if (empty == false)
  412.             {
  413.                 throw *this->saved;
  414.             }
  415.         }
  416.  
  417.         bool isEmpty() const
  418.         {
  419.             return this->empty;
  420.         }
  421.  
  422.     protected:
  423.         bool empty;
  424.  
  425.         _PythonException *saved;
  426. };
  427.  
  428. class ContinueException
  429. {
  430. };
  431.  
  432. class BreakException
  433. {
  434. };
  435.  
  436. // Helper functions for reference count handling in the fly.
  437. static PyObject *INCREASE_REFCOUNT( PyObject *object )
  438. {
  439.     assert( object->ob_refcnt > 0 );
  440.  
  441.     Py_INCREF( object );
  442.  
  443.     return object;
  444. }
  445.  
  446. static PyObject *DECREASE_REFCOUNT( PyObject *object )
  447. {
  448.     Py_DECREF( object );
  449.  
  450.     return object;
  451. }
  452.  
  453.  
  454. // Helper functions for print. Need to play nice with Python softspace behaviour.
  455.  
  456.  
  457. static void PRINT_ITEM_TO( PyObject *file, PyObject *object )
  458. {
  459.     PyObject *str = PyObject_Str( object );
  460.     PyObject *print;
  461.     bool softspace;
  462.  
  463.     if ( str == NULL )
  464.     {
  465.         PyErr_Clear();
  466.  
  467.         print = object;
  468.         softspace = false;
  469.     }
  470.     else
  471.     {
  472.         char *buffer;
  473.         Py_ssize_t length;
  474.  
  475.         int status = PyString_AsStringAndSize( str, &buffer, &length );
  476.         assert( status != -1 );
  477.  
  478.         softspace = length > 0 && buffer[length - 1 ] == '\t';
  479.  
  480.         print = str;
  481.     }
  482.  
  483.     // Check for soft space indicator, need to hold a reference to the file
  484.     // or else __getattr__ may release "file" in the mean time.
  485.     if ( PyFile_SoftSpace( file, !softspace ) )
  486.     {
  487.         if (unlikely( PyFile_WriteString( " ", file ) == -1 ))
  488.         {
  489.             Py_DECREF( file );
  490.             Py_DECREF( str );
  491.             throw _PythonException();
  492.         }
  493.     }
  494.  
  495.     if ( unlikely( PyFile_WriteObject( print, file, Py_PRINT_RAW ) == -1 ))
  496.     {
  497.         Py_XDECREF( str );
  498.         throw _PythonException();
  499.     }
  500.  
  501.     Py_XDECREF( str );
  502.  
  503.     if ( softspace )
  504.     {
  505.         PyFile_SoftSpace( file, !softspace );
  506.     }
  507. }
  508.  
  509. static void PRINT_NEW_LINE_TO( PyObject *file )
  510. {
  511.     if (unlikely( PyFile_WriteString( "\n", file ) == -1))
  512.     {
  513.         throw _PythonException();
  514.     }
  515.  
  516.     PyFile_SoftSpace( file, 0 );
  517. }
  518.  
  519. template<typename... P>
  520. static void PRINT_ITEMS( bool new_line, PyObject *file, P...eles )
  521. {
  522.     int size = sizeof...(eles);
  523.  
  524.     if ( file == NULL || file == Py_None )
  525.     {
  526.         file = PySys_GetObject((char *)"stdout");
  527.     }
  528.  
  529.     // Need to hold a reference for the case that the printing somehow removes
  530.     // the last reference to "file" while printing.
  531.     Py_INCREF( file );
  532.  
  533.     PyObject *elements[] = {eles...};
  534.  
  535.     for( int i = 0; i < size; i++ )
  536.     {
  537.         PRINT_ITEM_TO( file, elements[ i ] );
  538.     }
  539.  
  540.     if ( new_line )
  541.     {
  542.         PRINT_NEW_LINE_TO( file );
  543.     }
  544.  
  545.     // TODO: Use of PyObjectTemporary should be possible, this won't be
  546.     // exception safe otherwise
  547.     Py_DECREF( file );
  548. }
  549.  
  550.  
  551. static void PRINT_NEW_LINE( void )
  552. {
  553.     PyObject *stdout = PySys_GetObject((char *)"stdout");
  554.  
  555.     if (unlikely( stdout == NULL ))
  556.     {
  557.         PyErr_Format( PyExc_RuntimeError, "problem with stdout" );
  558.         throw _PythonException();
  559.     }
  560.  
  561.     PRINT_NEW_LINE_TO( stdout );
  562. }
  563.  
  564.  
  565. static void RAISE_EXCEPTION( PyObject *exception, PyTracebackObject *traceback )
  566. {
  567.     if ( PyExceptionClass_Check( exception ) )
  568.     {
  569.         throw _PythonException( exception, traceback );
  570.     }
  571.     else if ( PyExceptionInstance_Check( exception ) )
  572.     {
  573.         throw _PythonException( INCREASE_REFCOUNT( PyExceptionInstance_Class( exception ) ), exception, traceback );
  574.     }
  575.     else
  576.     {
  577.         PyErr_Format( PyExc_TypeError, "exceptions must be old-style classes or derived from BaseException, not %s", exception->ob_type->tp_name );
  578.         throw _PythonException();
  579.     }
  580. }
  581.  
  582. static void RAISE_EXCEPTION( PyObject *exception_type, PyObject *value, PyTracebackObject *traceback )
  583. {
  584.     // TODO: Check traceback
  585.  
  586.     if ( PyExceptionClass_Check( exception_type ) )
  587.     {
  588.        PyErr_NormalizeException( &exception_type, &value, (PyObject **)&traceback );
  589.     }
  590.  
  591.     throw _PythonException( exception_type, value, traceback );
  592. }
  593.  
  594. static inline void RAISE_EXCEPTION( PyObject *exception_type, PyObject *value, PyObject *traceback )
  595. {
  596.     RAISE_EXCEPTION( exception_type, value, (PyTracebackObject *)traceback );
  597. }
  598.  
  599.  
  600. static bool CHECK_IF_TRUE( PyObject *object )
  601. {
  602.     assert( object != NULL );
  603.     assert( object->ob_refcnt > 0 );
  604.  
  605.     int status = PyObject_IsTrue( object );
  606.  
  607.     if (unlikely( status == -1 ))
  608.     {
  609.         throw _PythonException();
  610.     }
  611.  
  612.     return status == 1;
  613. }
  614.  
  615. static bool CHECK_IF_FALSE( PyObject *object )
  616. {
  617.     assert( object != NULL );
  618.     assert( object->ob_refcnt > 0 );
  619.  
  620.     int status = PyObject_Not( object );
  621.  
  622.     if (unlikely( status == -1 ))
  623.     {
  624.         throw _PythonException();
  625.     }
  626.  
  627.     return status == 1;
  628. }
  629.  
  630. static PyObject *BOOL_FROM( bool value )
  631. {
  632.     return value ? _python_bool_True : _python_bool_False;
  633. }
  634.  
  635. static PyObject *UNARY_NOT( PyObject *object )
  636. {
  637.     int result = PyObject_Not( object );
  638.  
  639.     if (unlikely( result == -1 ))
  640.     {
  641.         throw _PythonException();
  642.     }
  643.  
  644.     return BOOL_FROM( result == 1 );
  645. }
  646.  
  647. typedef PyObject *(binary_api)( PyObject *, PyObject * );
  648.  
  649. static PyObject *BINARY_OPERATION( binary_api api, PyObject *operand1, PyObject *operand2 )
  650. {
  651.     int line = _current_line;
  652.  
  653.     PyObject *result = api( operand1, operand2 );
  654.  
  655.     if (unlikely (result == NULL))
  656.     {
  657.         _current_line = line;
  658.         throw _PythonException();
  659.     }
  660.  
  661.     return result;
  662. }
  663.  
  664. typedef PyObject *(unary_api)( PyObject * );
  665.  
  666. static PyObject *UNARY_OPERATION( unary_api api, PyObject *operand )
  667. {
  668.     PyObject *result = api( operand );
  669.  
  670.     if (unlikely (result == NULL))
  671.     {
  672.         throw _PythonException();
  673.     }
  674.  
  675.     return result;
  676. }
  677.  
  678. static PyObject *POWER_OPERATION( PyObject *operand1, PyObject *operand2 )
  679. {
  680.     PyObject *result = PyNumber_Power( operand1, operand2, Py_None );
  681.  
  682.     if (unlikely (result == NULL))
  683.     {
  684.         throw _PythonException();
  685.     }
  686.  
  687.     return result;
  688. }
  689.  
  690. static PyObject *POWER_OPERATION_INPLACE( PyObject *operand1, PyObject *operand2 )
  691. {
  692.     PyObject *result = PyNumber_InPlacePower( operand1, operand2, Py_None );
  693.  
  694.     if (unlikely (result == NULL))
  695.     {
  696.         throw _PythonException();
  697.     }
  698.  
  699.     return result;
  700. }
  701.  
  702. static PyObject *RICH_COMPARE( int opid, PyObject *operand2, PyObject *operand1 )
  703. {
  704.     int line = _current_line;
  705.     PyObject *result = PyObject_RichCompare( operand1, operand2, opid );
  706.  
  707.     if (unlikely (result == NULL))
  708.     {
  709.         _current_line = line;
  710.         throw _PythonException();
  711.     }
  712.  
  713.     return result;
  714. }
  715.  
  716. static bool RICH_COMPARE_BOOL( int opid, PyObject *operand2, PyObject *operand1 )
  717. {
  718.     int line = _current_line;
  719.     int result = PyObject_RichCompareBool( operand1, operand2, opid );
  720.  
  721.     if (unlikely( result == -1 ))
  722.     {
  723.         _current_line = line;
  724.         throw _PythonException();
  725.     }
  726.  
  727.     return result == 1;
  728. }
  729.  
  730.  
  731. static PyObject *SEQUENCE_CONTAINS( PyObject *sequence, PyObject *element)
  732. {
  733.     int result = PySequence_Contains( sequence, element );
  734.  
  735.     if (unlikely( result == -1 ))
  736.     {
  737.         throw _PythonException();
  738.     }
  739.  
  740.     return BOOL_FROM( result == 1 );
  741. }
  742.  
  743. static PyObject *SEQUENCE_CONTAINS_NOT( PyObject *sequence, PyObject *element)
  744. {
  745.     int result = PySequence_Contains( sequence, element );
  746.  
  747.     if (unlikely( result == -1 ))
  748.     {
  749.         throw _PythonException();
  750.     }
  751.  
  752.     return BOOL_FROM( result == 0 );
  753. }
  754.  
  755.  
  756. // Helper functions to debug the compiler operation.
  757. static void PRINT_REFCOUNT( PyObject *object )
  758. {
  759.    PyObject *stdout = PySys_GetObject((char *)"stdout");
  760.  
  761.    if (unlikely( stdout == NULL ))
  762.    {
  763.       PyErr_Format( PyExc_RuntimeError, "problem with stdout" );
  764.       throw _PythonException();
  765.    }
  766.  
  767.    char buffer[1024];
  768.    sprintf( buffer, " refcnt %d ", object->ob_refcnt );
  769.  
  770.    if (unlikely( PyFile_WriteString(buffer, stdout) == -1 ))
  771.    {
  772.       throw _PythonException();
  773.    }
  774.  
  775. }
  776.  
  777. static PyObject *CALL_FUNCTION( PyObject *named_args, PyObject *positional_args, PyObject *function_object )
  778. {
  779.     assert( function_object != NULL );
  780.     assert( function_object->ob_refcnt > 0 );
  781.     assert( positional_args != NULL );
  782.     assert( positional_args->ob_refcnt > 0 );
  783.     assert( named_args == NULL || named_args->ob_refcnt > 0 );
  784.  
  785.     int line = _current_line;
  786.  
  787.     PyObject *result = PyObject_Call( function_object, positional_args, named_args );
  788.  
  789.     if (unlikely (result == NULL))
  790.     {
  791.         _current_line = line;
  792.         throw _PythonException();
  793.     }
  794.  
  795.     return result;
  796. }
  797.  
  798. static PyObject *TO_TUPLE( PyObject *seq_obj )
  799. {
  800.     PyObject *result = PySequence_Tuple( seq_obj );
  801.  
  802.     if (unlikely (result == NULL))
  803.     {
  804.         throw _PythonException();
  805.     }
  806.  
  807.     return result;
  808. }
  809.  
  810. template<typename... P>
  811. static PyObject *MAKE_TUPLE( P...eles )
  812. {
  813.     int size = sizeof...(eles);
  814.  
  815.     if ( size > 0 )
  816.     {
  817.         PyObject *elements[] = {eles...};
  818.  
  819.         for ( Py_ssize_t i = 0; i < size; i++ )
  820.         {
  821.             assert (elements[ i ] != NULL);
  822.             assert (elements[ i ]->ob_refcnt > 0);
  823.         }
  824.  
  825.         PyObject *result = PyTuple_New( size );
  826.  
  827.         if (unlikely (result == NULL))
  828.         {
  829.             throw _PythonException();
  830.         }
  831.  
  832.         for ( Py_ssize_t i = 0; i < size; i++ )
  833.         {
  834.             PyTuple_SET_ITEM( result, i, INCREASE_REFCOUNT( elements[ size - 1 - i ] ));
  835.         }
  836.  
  837.         assert( result->ob_refcnt == 1 );
  838.  
  839.         return result;
  840.     }
  841.     else
  842.     {
  843.         return INCREASE_REFCOUNT( _python_tuple_empty );
  844.     }
  845. }
  846.  
  847. template<typename... P>
  848. static PyObject *MAKE_LIST( P...eles )
  849. {
  850.     PyObject *elements[] = {eles...};
  851.  
  852.     int size = sizeof...(eles);
  853.  
  854.     PyObject *result = PyList_New( size );
  855.  
  856.     if (unlikely (result == NULL))
  857.     {
  858.         throw _PythonException();
  859.     }
  860.  
  861.     for (Py_ssize_t i = 0; i < size; i++ )
  862.     {
  863.         assert (elements[ i ] != NULL);
  864.         assert (elements[ i ]->ob_refcnt > 0);
  865.  
  866.         PyList_SET_ITEM( result, i, elements[ size - 1 - i ] );
  867.     }
  868.  
  869.     assert( result->ob_refcnt == 1 );
  870.  
  871.     return result;
  872. }
  873.  
  874. template<typename... P>
  875. static PyObject *MAKE_DICT( P...eles )
  876. {
  877.     PyObject *elements[] = {eles...};
  878.     int size = sizeof...(eles);
  879.  
  880.     assert (size % 2 == 0);
  881.  
  882.     PyObject *result = PyDict_New();
  883.  
  884.     if (unlikely (result == NULL))
  885.     {
  886.         throw _PythonException();
  887.     }
  888.  
  889.     for( int i = 0; i < size; i += 2 )
  890.     {
  891.         int status = PyDict_SetItem( result, elements[i], elements[i+1] );
  892.  
  893.         if (unlikely( status == -1 ))
  894.         {
  895.             throw _PythonException();
  896.         }
  897.     }
  898.  
  899.     return result;
  900. }
  901.  
  902. static PyObject *MERGE_DICTS( PyObject *dict_a, PyObject *dict_b, bool allow_conflict )
  903. {
  904.     PyObject *result = PyDict_Copy( dict_a );
  905.  
  906.     if (unlikely (result == NULL))
  907.     {
  908.         throw _PythonException();
  909.     }
  910.  
  911.     int status = PyDict_Merge( result, dict_b, 1 );
  912.  
  913.     if (unlikely( status == -1 ))
  914.     {
  915.         throw _PythonException();
  916.     }
  917.  
  918.     if ( allow_conflict == false && PyDict_Size( dict_a ) + PyDict_Size( dict_b ) != PyDict_Size( result ))
  919.     {
  920.         Py_DECREF( result );
  921.  
  922.         PyErr_Format( PyExc_TypeError, "got multiple values for keyword argument" );
  923.         throw _PythonException();
  924.     }
  925.  
  926.     return result;
  927. }
  928.  
  929. static void DICT_SET_ITEM( PyObject *dict, PyObject *key, PyObject *value )
  930. {
  931.     int status = PyDict_SetItem( dict, key, value );
  932.  
  933.     if (unlikely( status == -1))
  934.     {
  935.         throw _PythonException();
  936.     }
  937. }
  938.  
  939. template<typename... P>
  940. static PyObject *MAKE_SET( P...eles )
  941. {
  942.     PyObject *tuple = MAKE_TUPLE( eles... );
  943.  
  944.     PyObject *result = PySet_New( tuple );
  945.  
  946.     Py_DECREF( tuple );
  947.  
  948.     if (unlikely (result == NULL))
  949.     {
  950.         throw _PythonException();
  951.     }
  952.  
  953.     return result;
  954. }
  955.  
  956. static PyObject *MAKE_STATIC_METHOD( PyObject *method )
  957. {
  958.     PyObject *attempt = PyStaticMethod_New( method );
  959.  
  960.     if ( attempt )
  961.     {
  962.         return attempt;
  963.     }
  964.     else
  965.     {
  966.         PyErr_Clear();
  967.  
  968.         return method;
  969.     }
  970. }
  971.  
  972. static PyObject *SEQUENCE_ELEMENT( PyObject *sequence, Py_ssize_t element )
  973. {
  974.     PyObject *result = PySequence_GetItem( sequence, element );
  975.  
  976.     if (unlikely (result == NULL))
  977.     {
  978.         throw _PythonException();
  979.     }
  980.  
  981.     return result;
  982. }
  983.  
  984. static PyObject *MAKE_ITERATOR( PyObject *iterated )
  985. {
  986.     PyObject *result = PyObject_GetIter( iterated );
  987.  
  988.     if (unlikely (result == NULL))
  989.     {
  990.         throw _PythonException();
  991.     }
  992.  
  993.     return result;
  994. }
  995.  
  996. // Return the next item of an iterator. Avoiding any exception for end of iteration, callers must
  997. // deal with NULL return as end of iteration, but will know it wasn't an Python exception, that will show as a thrown exception.
  998. static PyObject *ITERATOR_NEXT( PyObject *iterator )
  999. {
  1000.     assert( iterator != NULL );
  1001.     assert( iterator->ob_refcnt > 0 );
  1002.  
  1003.     int line = _current_line;
  1004.  
  1005.     PyObject *result = PyIter_Next( iterator );
  1006.  
  1007.     if (unlikely (result == NULL))
  1008.     {
  1009.         if ( PyErr_Occurred() != NULL )
  1010.         {
  1011.             _current_line = line;
  1012.  
  1013.             throw _PythonException();
  1014.         }
  1015.     }
  1016.     else
  1017.     {
  1018.         assert( result->ob_refcnt > 0 );
  1019.     }
  1020.  
  1021.     return result;
  1022. }
  1023.  
  1024. static inline PyObject *UNPACK_NEXT( PyObject *iterator, int seq_size_so_far )
  1025. {
  1026.     assert( iterator != NULL );
  1027.     assert( iterator->ob_refcnt > 0 );
  1028.  
  1029.     PyObject *result = PyIter_Next( iterator );
  1030.  
  1031.     if (unlikely (result == NULL))
  1032.     {
  1033.         if ( seq_size_so_far == 1 )
  1034.         {
  1035.             PyErr_Format( PyExc_ValueError, "need more than 1 value to unpack" );
  1036.         }
  1037.         else
  1038.         {
  1039.             PyErr_Format( PyExc_ValueError, "need more than %d values to unpack", seq_size_so_far );
  1040.         }
  1041.  
  1042.         throw _PythonException();
  1043.     }
  1044.  
  1045.     assert( result->ob_refcnt > 0 );
  1046.  
  1047.     return result;
  1048. }
  1049.  
  1050. static inline void UNPACK_ITERATOR_CHECK( PyObject *iterator )
  1051. {
  1052.     PyObject *attempt = PyIter_Next( iterator );
  1053.  
  1054.     if (likely( attempt == NULL ))
  1055.     {
  1056.         PyErr_Clear();
  1057.     }
  1058.     else
  1059.     {
  1060.         Py_DECREF( attempt );
  1061.  
  1062.         PyErr_Format( PyExc_ValueError, "too many values to unpack" );
  1063.         throw _PythonException();
  1064.     }
  1065. }
  1066.  
  1067.  
  1068. static PyObject *SELECT_IF_TRUE( PyObject *object )
  1069. {
  1070.     assert( object != NULL );
  1071.     assert( object->ob_refcnt > 0 );
  1072.  
  1073.     if ( CHECK_IF_TRUE( object ) )
  1074.     {
  1075.         return object;
  1076.     }
  1077.     else
  1078.     {
  1079.         Py_DECREF( object );
  1080.  
  1081.         return NULL;
  1082.     }
  1083. }
  1084.  
  1085. static PyObject *SELECT_IF_FALSE( PyObject *object )
  1086. {
  1087.     assert( object != NULL );
  1088.     assert( object->ob_refcnt > 0 );
  1089.  
  1090.     if ( CHECK_IF_FALSE( object ) )
  1091.     {
  1092.         return object;
  1093.     }
  1094.     else
  1095.     {
  1096.         Py_DECREF( object );
  1097.  
  1098.         return NULL;
  1099.     }
  1100. }
  1101.  
  1102. static PyObject *LOOKUP_SUBSCRIPT( PyObject *source, PyObject *subscript )
  1103. {
  1104.     assert (source);
  1105.     assert (source->ob_refcnt > 0);
  1106.     assert (subscript);
  1107.     assert (subscript->ob_refcnt > 0);
  1108.  
  1109.     PyObject *result = PyObject_GetItem( source, subscript );
  1110.  
  1111.     if (unlikely (result == NULL))
  1112.     {
  1113.         throw _PythonException();
  1114.     }
  1115.  
  1116.     return result;
  1117. }
  1118.  
  1119. static bool HAS_KEY( PyObject *source, PyObject *key )
  1120. {
  1121.     assert (source);
  1122.     assert (source->ob_refcnt > 0);
  1123.     assert (key);
  1124.     assert (key->ob_refcnt > 0);
  1125.  
  1126.     return PyMapping_HasKey( source, key ) != 0;
  1127. }
  1128.  
  1129. static PyObject *LOOKUP_VARS( PyObject *source )
  1130. {
  1131.     assert (source);
  1132.     assert (source->ob_refcnt > 0);
  1133.  
  1134.     static PyObject *dict_str = PyString_FromString( "__dict__" );
  1135.  
  1136.     PyObject *result = PyObject_GetAttr( source, dict_str );
  1137.  
  1138.     if (unlikely (result == NULL))
  1139.     {
  1140.         throw _PythonException();
  1141.     }
  1142.  
  1143.     return result;
  1144. }
  1145.  
  1146.  
  1147. static void SET_SUBSCRIPT( PyObject *target, PyObject *subscript, PyObject *value )
  1148. {
  1149.     assert (target);
  1150.     assert (target->ob_refcnt > 0);
  1151.     assert (subscript);
  1152.     assert (subscript->ob_refcnt > 0);
  1153.     assert (value);
  1154.     assert (value->ob_refcnt > 0);
  1155.  
  1156.     int status = PyObject_SetItem( target, subscript, value );
  1157.  
  1158.     if (unlikely( status == -1 ))
  1159.     {
  1160.         throw _PythonException();
  1161.     }
  1162. }
  1163.  
  1164. static void DEL_SUBSCRIPT( PyObject *target, PyObject *subscript )
  1165. {
  1166.     assert (target);
  1167.     assert (target->ob_refcnt > 0);
  1168.     assert (subscript);
  1169.     assert (subscript->ob_refcnt > 0);
  1170.  
  1171.     int status = PyObject_DelItem( target, subscript );
  1172.  
  1173.     if (unlikely( status == -1 ))
  1174.     {
  1175.         throw _PythonException();
  1176.     }
  1177. }
  1178.  
  1179.  
  1180. static PyObject *LOOKUP_SLICE( PyObject *source, Py_ssize_t lower, Py_ssize_t upper )
  1181. {
  1182.     assert (source);
  1183.     assert (source->ob_refcnt > 0);
  1184.  
  1185.     PyObject *result = PySequence_GetSlice( source, lower, upper);
  1186.  
  1187.     if (unlikely (result == NULL))
  1188.     {
  1189.         throw _PythonException();
  1190.     }
  1191.  
  1192.     return result;
  1193. }
  1194.  
  1195. static void SET_SLICE( PyObject *target, Py_ssize_t lower, Py_ssize_t upper, PyObject *value )
  1196. {
  1197.     assert (target);
  1198.     assert (target->ob_refcnt > 0);
  1199.     assert (value);
  1200.     assert (value->ob_refcnt > 0);
  1201.  
  1202.     int status = PySequence_SetSlice( target, lower, upper, value );
  1203.  
  1204.     if (unlikely( status == -1 ))
  1205.     {
  1206.         throw _PythonException();
  1207.     }
  1208. }
  1209.  
  1210. static Py_ssize_t CONVERT_TO_INDEX( PyObject *value );
  1211.  
  1212. static void DEL_SLICE( PyObject *target, PyObject *lower, PyObject *upper )
  1213. {
  1214.     assert (target);
  1215.     assert (target->ob_refcnt > 0);
  1216.  
  1217.     if ( target->ob_type->tp_as_sequence && target->ob_type->tp_as_sequence->sq_ass_slice )
  1218.     {
  1219.         int status = PySequence_DelSlice( target, lower != Py_None ? CONVERT_TO_INDEX( lower ) : 0, upper != Py_None ? CONVERT_TO_INDEX( upper ) : PY_SSIZE_T_MAX );
  1220.  
  1221.         if (unlikely( status == -1 ))
  1222.         {
  1223.             throw _PythonException();
  1224.         }
  1225.     }
  1226.     else
  1227.     {
  1228.         PyObject *slice = PySlice_New( lower, upper, NULL );
  1229.  
  1230.         if (slice == NULL)
  1231.         {
  1232.             throw _PythonException();
  1233.         }
  1234.  
  1235.         int status = PyObject_DelItem( target, slice );
  1236.  
  1237.         Py_DECREF( slice );
  1238.  
  1239.         if (unlikely( status == -1 ))
  1240.         {
  1241.             throw _PythonException();
  1242.         }
  1243.     }
  1244. }
  1245.  
  1246. static PyObject *MAKE_SLICEOBJ( PyObject *start, PyObject *stop, PyObject *step )
  1247. {
  1248.     assert (start);
  1249.     assert (start->ob_refcnt > 0);
  1250.     assert (stop);
  1251.     assert (stop->ob_refcnt > 0);
  1252.     assert (step);
  1253.     assert (step->ob_refcnt > 0);
  1254.  
  1255.     PyObject *result = PySlice_New( start, stop, step );
  1256.  
  1257.     if (unlikely (result == NULL))
  1258.     {
  1259.         throw _PythonException();
  1260.     }
  1261.  
  1262.     return result;
  1263. }
  1264.  
  1265. static Py_ssize_t CONVERT_TO_INDEX( PyObject *value )
  1266. {
  1267.     assert (value);
  1268.     assert (value->ob_refcnt > 0);
  1269.  
  1270.     if ( PyInt_Check( value ) )
  1271.     {
  1272.         return PyInt_AS_LONG( value );
  1273.     }
  1274.     else if ( PyIndex_Check( value ) )
  1275.     {
  1276.         Py_ssize_t result = PyNumber_AsSsize_t( value, NULL );
  1277.  
  1278.         if (unlikely( result == -1 && PyErr_Occurred() ))
  1279.         {
  1280.             throw _PythonException();
  1281.         }
  1282.  
  1283.         return result;
  1284.     }
  1285.     else
  1286.     {
  1287.         PyErr_Format( PyExc_TypeError, "slice indices must be integers or None or have an __index__ method" );
  1288.         throw _PythonException();
  1289.     }
  1290. }
  1291.  
  1292. static PyObject *LOOKUP_ATTRIBUTE( PyObject *source, PyObject *attr_name )
  1293. {
  1294.     assert (source);
  1295.     assert (source->ob_refcnt > 0);
  1296.     assert (attr_name);
  1297.     assert (attr_name->ob_refcnt > 0);
  1298.  
  1299.     PyObject *result = PyObject_GetAttr( source, attr_name );
  1300.  
  1301.     if (unlikely (result == NULL))
  1302.     {
  1303.         throw _PythonException();
  1304.     }
  1305.  
  1306.     assert( result->ob_refcnt > 0 );
  1307.  
  1308.     return result;
  1309. }
  1310.  
  1311. static void SET_ATTRIBUTE( PyObject *target, PyObject *attr_name, PyObject *value )
  1312. {
  1313.     assert (target);
  1314.     assert (target->ob_refcnt > 0);
  1315.     assert (attr_name);
  1316.     assert (attr_name->ob_refcnt > 0);
  1317.     assert (value);
  1318.     assert (value->ob_refcnt > 0);
  1319.  
  1320.     int status = PyObject_SetAttr( target, attr_name, value );
  1321.  
  1322.     if (unlikely( status == -1 ))
  1323.     {
  1324.         throw _PythonException();
  1325.     }
  1326. }
  1327.  
  1328. static void DEL_ATTRIBUTE( PyObject *target, PyObject *attr_name )
  1329. {
  1330.     assert (target);
  1331.     assert (target->ob_refcnt > 0);
  1332.     assert (attr_name);
  1333.     assert (attr_name->ob_refcnt > 0);
  1334.  
  1335.     int status = PyObject_DelAttr( target, attr_name );
  1336.  
  1337.     if (unlikely( status == -1 ))
  1338.     {
  1339.         throw _PythonException();
  1340.     }
  1341. }
  1342.  
  1343.  
  1344. static void APPEND_TO_LIST( PyObject *list, PyObject *item)
  1345. {
  1346.     int status = PyList_Append( list, item );
  1347.  
  1348.     if (unlikely( status == -1 ))
  1349.     {
  1350.         throw _PythonException();
  1351.     }
  1352. }
  1353.  
  1354. static PyObject *SEQUENCE_CONCAT( PyObject *seq1, PyObject *seq2 )
  1355. {
  1356.  
  1357.     PyObject *result = PySequence_Concat( seq1, seq2 );
  1358.  
  1359.     if (unlikely (result == NULL))
  1360.     {
  1361.         throw _PythonException();
  1362.     }
  1363.  
  1364.     return result;
  1365. }
  1366.  
  1367. // Helper class to be used when PyObject * are provided as parameters where they
  1368. // are not consumed, but not needed anymore after the call and and need a release
  1369. // as soon as possible.
  1370.  
  1371. class PyObjectTemporary {
  1372.     public:
  1373.         explicit PyObjectTemporary( PyObject *object )
  1374.         {
  1375.             assert( object );
  1376.             assert( object->ob_refcnt > 0 );
  1377.  
  1378.             this->object = object;
  1379.         }
  1380.  
  1381.         PyObjectTemporary( const PyObjectTemporary &object ) = delete;
  1382.  
  1383.         ~PyObjectTemporary()
  1384.         {
  1385.             Py_DECREF( this->object );
  1386.         }
  1387.  
  1388.         PyObject *asObject()
  1389.         {
  1390.             assert( this->object->ob_refcnt > 0 );
  1391.  
  1392.             return this->object;
  1393.         }
  1394.  
  1395.         void assign( PyObject *object )
  1396.         {
  1397.             Py_DECREF( this->object );
  1398.  
  1399.             assert( object );
  1400.             assert( object->ob_refcnt > 0 );
  1401.  
  1402.             this->object = object;
  1403.         }
  1404.  
  1405.         void checkSanity( char const *message ) const
  1406.         {
  1407.             if ( this->object->ob_refcnt <= 0 )
  1408.             {
  1409.                 puts( message );
  1410.                 assert( false );
  1411.             }
  1412.         }
  1413.     private:
  1414.         PyObject *object;
  1415. };
  1416.  
  1417. class PyObjectLocalDictVariable {
  1418.     public:
  1419.         explicit PyObjectLocalDictVariable( PyObject *storage, PyObject *var_name, PyObject *object = NULL )
  1420.         {
  1421.             this->storage    = storage;
  1422.             this->var_name   = var_name;
  1423.  
  1424.             if ( object != NULL )
  1425.             {
  1426.                 int status = PyDict_SetItem( this->storage, this->var_name, object );
  1427.                 assert( status == 0 );
  1428.             }
  1429.         }
  1430.  
  1431.         PyObject *asObject() const
  1432.         {
  1433.             // TODO: Dictionary quick access code could be used here too.
  1434.             PyObject *result = PyDict_GetItem( this->storage, this->var_name );
  1435.  
  1436.             if (unlikely (result == NULL))
  1437.             {
  1438.                 PyErr_Format( PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", PyString_AsString( this->var_name ) );
  1439.                 throw _PythonException();
  1440.             }
  1441.  
  1442.             assert( result->ob_refcnt > 0 );
  1443.  
  1444.             return result;
  1445.         }
  1446.  
  1447.         void operator=( PyObject *object )
  1448.         {
  1449.             assert( object );
  1450.             assert( object->ob_refcnt > 0 );
  1451.  
  1452.             int status = PyDict_SetItem( this->storage, this->var_name, object );
  1453.             assert( status == 0 );
  1454.         }
  1455.  
  1456.         bool isInitialized() const
  1457.         {
  1458.             return PyDict_Contains( this->storage, this->var_name ) == 1;
  1459.         }
  1460.  
  1461.         void del()
  1462.         {
  1463.             int status = PyDict_DelItem( this->storage, this->var_name );
  1464.  
  1465.             if (unlikely( status == -1 ))
  1466.             {
  1467.                 // TODO: Probably an error should be raised?
  1468.                 PyErr_Clear();
  1469.             }
  1470.         }
  1471.  
  1472.  
  1473.         PyObject *getVariableName() const
  1474.         {
  1475.             return this->var_name;
  1476.         }
  1477.  
  1478.     private:
  1479.         PyObject *storage;
  1480.         PyObject *var_name;
  1481. };
  1482.  
  1483. class PyObjectLocalVariable {
  1484.     public:
  1485.         explicit PyObjectLocalVariable( PyObject *var_name, PyObject *object = NULL, bool free_value = true )
  1486.         {
  1487.             this->var_name   = var_name;
  1488.             this->object     = object;
  1489.             this->free_value = free_value;
  1490.         }
  1491.  
  1492.         explicit PyObjectLocalVariable() {
  1493.             this->var_name   = NULL;
  1494.             this->object     = NULL;
  1495.             this->free_value = false;
  1496.         }
  1497.  
  1498.         ~PyObjectLocalVariable()
  1499.         {
  1500.             if ( this->free_value )
  1501.             {
  1502.                 // TODO: Why would free_value be true if this->object were NULL.
  1503.                 Py_XDECREF( this->object );
  1504.             }
  1505.         }
  1506.  
  1507.         void setVariableName( PyObject *var_name )
  1508.         {
  1509.             assert( var_name );
  1510.             assert( var_name->ob_refcnt > 0 );
  1511.  
  1512.             assert( this->var_name == NULL);
  1513.  
  1514.             this->var_name = var_name;
  1515.         }
  1516.  
  1517.         void operator=( PyObject *object )
  1518.         {
  1519.             assert( object );
  1520.             assert( object->ob_refcnt > 0 );
  1521.  
  1522.             PyObject *old_object = this->free_value ? this->object : NULL;
  1523.  
  1524.             this->object = object;
  1525.             this->free_value = true;
  1526.  
  1527.             // Free old value if any available and owned.
  1528.             Py_XDECREF( old_object );
  1529.         }
  1530.  
  1531.         PyObject *asObject() const
  1532.         {
  1533.             if ( this->object == NULL && this->var_name != NULL )
  1534.             {
  1535.                 PyErr_Format( PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", PyString_AsString( this->var_name ) );
  1536.                 throw _PythonException();
  1537.             }
  1538.  
  1539.             assert( this->object );
  1540.             assert( this->object->ob_refcnt > 0 );
  1541.  
  1542.             return this->object;
  1543.         }
  1544.  
  1545.         bool isInitialized() const
  1546.         {
  1547.             return this->object != NULL;
  1548.         }
  1549.  
  1550.         void del()
  1551.         {
  1552.             if ( this->object == NULL )
  1553.             {
  1554.                 PyErr_Format( PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", PyString_AsString( this->var_name ) );
  1555.                 throw _PythonException();
  1556.             }
  1557.  
  1558.             if ( this->free_value )
  1559.             {
  1560.                 Py_DECREF( this->object );
  1561.             }
  1562.  
  1563.             this->object = NULL;
  1564.             this->free_value = true;
  1565.         }
  1566.  
  1567.         PyObject *getVariableName() const
  1568.         {
  1569.             return this->var_name;
  1570.         }
  1571.  
  1572.     private:
  1573.  
  1574.         PyObject *var_name;
  1575.         PyObject *object;
  1576.         bool free_value;
  1577. };
  1578.  
  1579. class PyObjectSharedStorage
  1580. {
  1581.     public:
  1582.         explicit PyObjectSharedStorage( PyObject *var_name, PyObject *object, bool free_value )
  1583.         {
  1584.             assert( object == NULL || object->ob_refcnt > 0 );
  1585.  
  1586.             this->var_name   = var_name;
  1587.             this->object     = object;
  1588.             this->free_value = free_value;
  1589.             this->ref_count  = 1;
  1590.         }
  1591.  
  1592.         ~PyObjectSharedStorage()
  1593.         {
  1594.             if ( this->free_value )
  1595.             {
  1596.                 Py_XDECREF( this->object );
  1597.             }
  1598.         }
  1599.  
  1600.         void operator=( PyObject *object )
  1601.         {
  1602.             assert( object );
  1603.             assert( object->ob_refcnt > 0 );
  1604.  
  1605.             PyObject *old_object = this->free_value ? this->object : NULL;
  1606.  
  1607.             this->object = object;
  1608.             this->free_value = true;
  1609.  
  1610.             // Free old value if any available and owned.
  1611.             Py_XDECREF( old_object );
  1612.         }
  1613.  
  1614.         PyObject *var_name;
  1615.         PyObject *object;
  1616.         bool free_value;
  1617.         int ref_count;
  1618. };
  1619.  
  1620. class PyObjectSharedLocalVariable
  1621. {
  1622.     public:
  1623.         explicit PyObjectSharedLocalVariable( PyObject *var_name, PyObject *object = NULL, bool free_value = true )
  1624.         {
  1625.             this->storage = new PyObjectSharedStorage( var_name, object, free_value );
  1626.         }
  1627.  
  1628.         explicit PyObjectSharedLocalVariable()
  1629.         {
  1630.             this->storage = NULL;
  1631.         }
  1632.  
  1633.         ~PyObjectSharedLocalVariable()
  1634.         {
  1635.             if ( this->storage )
  1636.             {
  1637.                 assert( this->storage->ref_count > 0 );
  1638.                 this->storage->ref_count -= 1;
  1639.  
  1640.                 if (this->storage->ref_count == 0)
  1641.                 {
  1642.                     delete this->storage;
  1643.                 }
  1644.             }
  1645.         }
  1646.  
  1647.         void setVariableName( PyObject *var_name )
  1648.         {
  1649.             assert( this->storage == NULL );
  1650.  
  1651.             this->storage = new PyObjectSharedStorage( var_name, NULL, false );
  1652.         }
  1653.  
  1654.         void shareWith( const PyObjectSharedLocalVariable &other )
  1655.         {
  1656.             assert(this->storage == NULL);
  1657.             assert(other.storage != NULL);
  1658.  
  1659.             this->storage = other.storage;
  1660.             this->storage->ref_count += 1;
  1661.         }
  1662.  
  1663.         void operator=( PyObject *object )
  1664.         {
  1665.             this->storage->operator=( object );
  1666.         }
  1667.  
  1668.         PyObject *asObject() const
  1669.         {
  1670.             assert( this->storage );
  1671.  
  1672.             if ( this->storage->object == NULL )
  1673.             {
  1674.                 PyErr_Format( PyExc_UnboundLocalError, "free variable '%s' referenced before assignment in enclosing scope", PyString_AsString( this->storage->var_name ) );
  1675.                 throw _PythonException();
  1676.  
  1677.             }
  1678.  
  1679.             if ( (this->storage->object)->ob_refcnt == 0 )
  1680.             {
  1681.                 PyErr_Format( PyExc_UnboundLocalError, "free variable '%s' referenced after its finalization in enclosing scope", PyString_AsString( this->storage->var_name ) );
  1682.                 throw _PythonException();
  1683.             }
  1684.  
  1685.             return this->storage->object;
  1686.         }
  1687.  
  1688.         bool isInitialized() const
  1689.         {
  1690.             return this->storage->object != NULL;
  1691.         }
  1692.  
  1693.         PyObject *getVariableName() const
  1694.         {
  1695.             return this->storage->var_name;
  1696.         }
  1697.  
  1698.     private:
  1699.         PyObjectSharedLocalVariable( PyObjectSharedLocalVariable & );
  1700.  
  1701.         PyObjectSharedStorage *storage;
  1702. };
  1703.  
  1704. static PyDictEntry *GET_PYDICT_ENTRY( PyModuleObject *module, PyStringObject *key )
  1705. {
  1706.     // Idea similar to LOAD_GLOBAL in CPython. Because the variable name is a string, we
  1707.     // can shortcut much of the dictionary code by using its hash and dictionary knowledge
  1708.     // here. Only improvement would be to identify how to ensure that the hash is computed
  1709.     // already. Calling hash early on could do that potentially.
  1710.  
  1711.     long hash = key->ob_shash;
  1712.  
  1713.     if ( hash == -1 )
  1714.     {
  1715.         hash = PyString_Type.tp_hash( (PyObject *)key );
  1716.     }
  1717.  
  1718.     PyDictObject *dict = (PyDictObject *)(module->md_dict);
  1719.     assert( PyDict_CheckExact( dict ));
  1720.  
  1721.     PyDictEntry *entry = dict->ma_lookup( dict, (PyObject *)key, hash );
  1722.  
  1723.     // The "entry" cannot be NULL, it can only be empty for a string dict lookup, but at
  1724.     // least assert it.
  1725.     assert( entry != NULL );
  1726.  
  1727.     return entry;
  1728. }
  1729.  
  1730. class PyObjectGlobalVariable
  1731. {
  1732.     public:
  1733.         explicit PyObjectGlobalVariable( PyObject **module_ptr, PyObject **var_name )
  1734.         {
  1735.             assert( module_ptr );
  1736.             assert( var_name );
  1737.  
  1738.             this->module_ptr = (PyModuleObject **)module_ptr;
  1739.             this->var_name   = (PyStringObject **)var_name;
  1740.         }
  1741.  
  1742.         PyObject *asObject() const
  1743.         {
  1744.             PyDictEntry *entry = GET_PYDICT_ENTRY( *this->module_ptr, *this->var_name );
  1745.  
  1746.             if (likely( entry->me_value != NULL ))
  1747.             {
  1748.                 return INCREASE_REFCOUNT( entry->me_value );
  1749.             }
  1750.  
  1751.             entry = GET_PYDICT_ENTRY( _module_builtin, *this->var_name );
  1752.  
  1753.             if (likely( entry->me_value != NULL ))
  1754.             {
  1755.                 return INCREASE_REFCOUNT( entry->me_value );
  1756.             }
  1757.  
  1758.             PyErr_Format( PyExc_NameError, "global name %s is not defined", PyString_AsString( (PyObject *)*this->var_name ) );
  1759.             throw _PythonException();
  1760.         }
  1761.  
  1762.         PyObject *asObject( PyObject *dict ) const
  1763.         {
  1764.             if ( PyDict_Contains( dict, (PyObject *)*this->var_name ) )
  1765.             {
  1766.                 return PyDict_GetItem( dict, (PyObject *)*this->var_name );
  1767.             }
  1768.             else
  1769.             {
  1770.                 return this->asObject();
  1771.             }
  1772.         }
  1773.  
  1774.         void assign( PyObject *value ) const
  1775.         {
  1776.             PyDictEntry *entry = GET_PYDICT_ENTRY( *this->module_ptr, *this->var_name );
  1777.  
  1778.             // Values are more likely set than not set, in that case speculatively try the
  1779.             // quickest access method.
  1780.             if (likely( entry->me_value != NULL ))
  1781.             {
  1782.                 PyObject *old = entry->me_value;
  1783.                 entry->me_value = value;
  1784.  
  1785.                 Py_DECREF( old );
  1786.             }
  1787.             else
  1788.             {
  1789.                 DICT_SET_ITEM( (*this->module_ptr)->md_dict, (PyObject *)*this->var_name, value );
  1790.                 Py_DECREF( value );
  1791.             }
  1792.         }
  1793.  
  1794.         void assign0( PyObject *value ) const
  1795.         {
  1796.             DICT_SET_ITEM( (*this->module_ptr)->md_dict, (PyObject *)*this->var_name, value );
  1797.         }
  1798.  
  1799.         void del() const
  1800.         {
  1801.             int status = PyDict_DelItem( (*this->module_ptr)->md_dict, (PyObject *)*this->var_name );
  1802.  
  1803.             if (unlikely( status == -1 ))
  1804.             {
  1805.                 PyErr_Format( PyExc_NameError, "name '%s' is not defined", PyString_AsString( (PyObject *)*this->var_name ) );
  1806.                 throw _PythonException();
  1807.             }
  1808.         }
  1809.  
  1810.         bool isInitialized() const
  1811.         {
  1812.             PyDictEntry *entry = GET_PYDICT_ENTRY( *this->module_ptr, *this->var_name );
  1813.  
  1814.             if (likely( entry->me_value != NULL ))
  1815.             {
  1816.                 return true;
  1817.             }
  1818.  
  1819.             entry = GET_PYDICT_ENTRY( _module_builtin, *this->var_name );
  1820.  
  1821.             return entry->me_value != NULL;
  1822.         }
  1823.  
  1824.     private:
  1825.        PyModuleObject **module_ptr;
  1826.        PyStringObject **var_name;
  1827. };
  1828.  
  1829. static PyObject *MAKE_LOCALS_DICT( void )
  1830. {
  1831.     return MAKE_DICT();
  1832. }
  1833.  
  1834. template<typename T>
  1835. static void FILL_LOCALS_DICT( PyObject *dict, T variable )
  1836. {
  1837.     if ( variable->isInitialized() )
  1838.     {
  1839.         int status = PyDict_SetItem( dict, variable->getVariableName(), variable->asObject() );
  1840.  
  1841.         if (unlikely( status == -1 ))
  1842.         {
  1843.             throw _PythonException();
  1844.         }
  1845.     }
  1846. }
  1847.  
  1848. template<typename T, typename... P>
  1849. static void FILL_LOCALS_DICT( PyObject *dict, T variable, P... variables )
  1850. {
  1851.     if ( variable->isInitialized() )
  1852.     {
  1853.         int status = PyDict_SetItem( dict, variable->getVariableName(), variable->asObject() );
  1854.  
  1855.         if (unlikely( status == -1 ))
  1856.         {
  1857.             throw _PythonException();
  1858.         }
  1859.     }
  1860.  
  1861.     FILL_LOCALS_DICT( dict, variables... );
  1862. }
  1863.  
  1864. template<typename... P>
  1865. static PyObject *MAKE_LOCALS_DICT( P...variables )
  1866. {
  1867.     PyObject *result = MAKE_LOCALS_DICT();
  1868.  
  1869.     FILL_LOCALS_DICT( result, variables... );
  1870.  
  1871.     return result;
  1872. }
  1873.  
  1874. static PyObject *MAKE_LOCALS_DIR( void )
  1875. {
  1876.     return MAKE_LIST();
  1877. }
  1878.  
  1879. template<typename T>
  1880. static void FILL_LOCALS_DIR( PyObject *list, T variable )
  1881. {
  1882.     if ( variable->isInitialized() )
  1883.     {
  1884.         int status = PyList_Append( list, variable->getVariableName() );
  1885.  
  1886.         if (unlikely( status == -1 ))
  1887.         {
  1888.             throw _PythonException();
  1889.         }
  1890.     }
  1891. }
  1892.  
  1893. template<typename T, typename... P>
  1894. static void FILL_LOCALS_DIR( PyObject *list, T variable, P... variables )
  1895. {
  1896.     if ( variable->isInitialized() )
  1897.     {
  1898.         int status = PyList_Append( list, variable->getVariableName() );
  1899.  
  1900.         if (unlikely( status == -1 ))
  1901.         {
  1902.             throw _PythonException();
  1903.         }
  1904.     }
  1905.  
  1906.     FILL_LOCALS_DIR( list, variables... );
  1907. }
  1908.  
  1909. template<typename... P>
  1910. static PyObject *MAKE_LOCALS_DIR( P...variables )
  1911. {
  1912.     PyObject *result = MAKE_LOCALS_DIR();
  1913.  
  1914.     FILL_LOCALS_DIR( result, variables... );
  1915.  
  1916.     return result;
  1917. }
  1918.  
  1919. static PyObject *TUPLE_COPY( PyObject *tuple )
  1920. {
  1921.     assert( tuple != NULL );
  1922.     assert( tuple->ob_refcnt > 0 );
  1923.  
  1924.     assert( PyTuple_CheckExact( tuple ) );
  1925.  
  1926.     Py_ssize_t size = PyTuple_GET_SIZE( tuple );
  1927.  
  1928.     PyObject *result = PyTuple_New( size );
  1929.  
  1930.     if (unlikely (result == NULL))
  1931.     {
  1932.         throw _PythonException();
  1933.     }
  1934.  
  1935.     for ( Py_ssize_t i = 0; i < size; i++ )
  1936.     {
  1937.         PyTuple_SET_ITEM( result, i, INCREASE_REFCOUNT( PyTuple_GET_ITEM( tuple, i ) ) );
  1938.     }
  1939.  
  1940.     return result;
  1941. }
  1942.  
  1943. static PyObject *LIST_COPY( PyObject *list )
  1944. {
  1945.     assert( list != NULL );
  1946.     assert( list->ob_refcnt > 0 );
  1947.  
  1948.     assert( PyList_CheckExact( list ) );
  1949.  
  1950.     Py_ssize_t size = PyList_GET_SIZE( list );
  1951.  
  1952.     PyObject *result = PyList_New( size );
  1953.  
  1954.     if (unlikely (result == NULL))
  1955.     {
  1956.         throw _PythonException();
  1957.     }
  1958.  
  1959.     for ( Py_ssize_t i = 0; i < size; i++ )
  1960.     {
  1961.         PyList_SET_ITEM( result, i, INCREASE_REFCOUNT( PyList_GET_ITEM( list, i ) ) );
  1962.     }
  1963.  
  1964.     return result;
  1965. }
  1966.  
  1967.  
  1968. class PythonBuiltin
  1969. {
  1970.     public:
  1971.         explicit PythonBuiltin( char const *name )
  1972.         {
  1973.             this->name = name;
  1974.             this->value = NULL;
  1975.         }
  1976.  
  1977.         PyObject *asObject()
  1978.         {
  1979.             if ( this->value == NULL )
  1980.             {
  1981.                 // TODO: Use GET_PYDICT_ENTRY here too.
  1982.                 this->value = PyObject_GetAttrString( (PyObject *)_module_builtin, this->name );
  1983.             }
  1984.  
  1985.             assert( this->value != NULL );
  1986.  
  1987.             return this->value;
  1988.         }
  1989.  
  1990.     private:
  1991.         char const *name;
  1992.         PyObject *value;
  1993. };
  1994.  
  1995. static PythonBuiltin _python_builtin_compile( "compile" );
  1996.  
  1997. static PyObject *COMPILE_CODE( PyObject *source_code, PyObject *file_name, PyObject *mode, int flags )
  1998. {
  1999.     // May be a source, but also could already be a compiled object, in which case this
  2000.     // should just return it.
  2001.     if ( PyCode_Check( source_code ) )
  2002.     {
  2003.         return INCREASE_REFCOUNT( source_code );
  2004.     }
  2005.  
  2006.     // Workaround leading whitespace causing a trouble to compile builtin, but not eval builtin
  2007.     PyObject *source;
  2008.  
  2009.     if ( ( PyString_Check( source_code ) || PyUnicode_Check( source_code ) ) && strcmp( PyString_AsString( mode ), "exec" ) != 0 )
  2010.     {
  2011.         static PyObject *strip_str = PyString_FromString( "strip" );
  2012.  
  2013.         // TODO: There is an API to call a method, use it instead.
  2014.         source = LOOKUP_ATTRIBUTE( source_code, strip_str );
  2015.         source = PyObject_CallFunctionObjArgs( source, NULL );
  2016.  
  2017.         assert( source );
  2018.     }
  2019.     else if ( PyFile_Check( source_code ) && strcmp( PyString_AsString( mode ), "exec" ) == 0 )
  2020.     {
  2021.         static PyObject *read_str = PyString_FromString( "read" );
  2022.  
  2023.         // TODO: There is an API to call a method, use it instead.
  2024.         source = LOOKUP_ATTRIBUTE( source_code, read_str );
  2025.         source = PyObject_CallFunctionObjArgs( source, NULL );
  2026.  
  2027.         assert( source );
  2028.     }
  2029.     else
  2030.     {
  2031.         source = source_code;
  2032.     }
  2033.  
  2034.     PyObject *future_flags = PyInt_FromLong( flags );
  2035.  
  2036.     PyObject *result = PyObject_CallFunctionObjArgs(
  2037.         _python_builtin_compile.asObject(),
  2038.         source,
  2039.         file_name,
  2040.         mode,
  2041.         future_flags,      // flags
  2042.         _python_bool_True, // dont_inherit
  2043.         NULL
  2044.     );
  2045.  
  2046.     Py_DECREF( future_flags );
  2047.  
  2048.     if (unlikely (result == NULL))
  2049.     {
  2050.         throw _PythonException();
  2051.     }
  2052.  
  2053.     return result;
  2054. }
  2055.  
  2056. static PythonBuiltin _python_builtin_open( "open" );
  2057.  
  2058. static PyObject *OPEN_FILE( PyObject *file_name, PyObject *mode, PyObject *buffering )
  2059. {
  2060.     PyObject *result = PyObject_CallFunctionObjArgs(
  2061.         _python_builtin_open.asObject(),
  2062.         file_name,
  2063.         mode,
  2064.         buffering,
  2065.         NULL
  2066.     );
  2067.  
  2068.     if (unlikely (result == NULL))
  2069.     {
  2070.         throw _PythonException();
  2071.     }
  2072.  
  2073.     return result;
  2074. }
  2075.  
  2076. static PyObject *EVAL_CODE( PyObject *code, PyObject *globals, PyObject *locals )
  2077. {
  2078.     if ( PyDict_Check( globals ) == 0 )
  2079.     {
  2080.         PyErr_Format( PyExc_TypeError, "exec: arg 2 must be a dictionary or None" );
  2081.         throw _PythonException();
  2082.     }
  2083.  
  2084.     if ( locals == NULL || locals == Py_None )
  2085.     {
  2086.         locals = globals;
  2087.     }
  2088.  
  2089.     if ( PyMapping_Check( locals ) == 0 )
  2090.     {
  2091.         PyErr_Format( PyExc_TypeError, "exec: arg 3 must be a mapping or None" );
  2092.         throw _PythonException();
  2093.     }
  2094.  
  2095.     // Set the __builtin__ in globals, it is expected to be present.
  2096.     if ( PyMapping_HasKeyString( globals, (char *)"__builtins__" ) == 0 )
  2097.     {
  2098.         if ( PyMapping_SetItemString( globals, (char *)"__builtins__", (PyObject *)_module_builtin ) == -1 )
  2099.         {
  2100.             throw _PythonException();
  2101.         }
  2102.     }
  2103.  
  2104.     PyObject *result = PyEval_EvalCode( (PyCodeObject *)code, globals, locals );
  2105.  
  2106.     if (unlikely (result == NULL))
  2107.     {
  2108.         throw _PythonException();
  2109.     }
  2110.  
  2111.     return result;
  2112. }
  2113.  
  2114. static PyObject *empty_code = PyBuffer_FromMemory( NULL, 0 );
  2115.  
  2116. static PyCodeObject *MAKE_CODEOBJ( PyObject *filename, PyObject *function_name, int line )
  2117. {
  2118.     // TODO: Potentially it is possible to create a line2no table that will allow to use
  2119.     // only one code object per function, this could then be cached and presumably be much
  2120.     // faster, because it could be reused.
  2121.  
  2122.     assert( PyString_Check( filename ));
  2123.     assert( PyString_Check( function_name ));
  2124.  
  2125.     assert( empty_code );
  2126.  
  2127.     // printf( "MAKE_CODEOBJ code object %d\n", empty_code->ob_refcnt );
  2128.  
  2129.     PyCodeObject *result = PyCode_New (
  2130.         0, 0, 0, 0, // argcount, locals, stacksize, flags
  2131.         empty_code, //
  2132.         _python_tuple_empty,
  2133.         _python_tuple_empty,
  2134.         _python_tuple_empty,
  2135.         _python_tuple_empty,
  2136.         _python_tuple_empty,
  2137.         filename,
  2138.         function_name,
  2139.         line,
  2140.         _python_str_empty
  2141.     );
  2142.  
  2143.     if (unlikely( result == NULL ))
  2144.     {
  2145.         throw _PythonException();
  2146.     }
  2147.  
  2148.     return result;
  2149. }
  2150.  
  2151. static PyFrameObject *MAKE_FRAME( PyObject *module, PyObject *filename, PyObject *function_name, int line )
  2152. {
  2153.     PyCodeObject *code = MAKE_CODEOBJ( filename, function_name, line );
  2154.  
  2155.     PyFrameObject *result = PyFrame_New(
  2156.         PyThreadState_GET(),
  2157.         code,
  2158.         ((PyModuleObject *)module)->md_dict,
  2159.         NULL // No locals yet
  2160.     );
  2161.  
  2162.     Py_DECREF( code );
  2163.  
  2164.     if (unlikely( result == NULL ))
  2165.     {
  2166.         throw _PythonException();
  2167.     }
  2168.  
  2169.     result->f_lineno = line;
  2170.  
  2171.     return result;
  2172. }
  2173.  
  2174. static PyTracebackObject *MAKE_TRACEBACK_START( PyFrameObject *frame, int line )
  2175. {
  2176.     PyTracebackObject *result = PyObject_GC_New( PyTracebackObject, &PyTraceBack_Type );
  2177.  
  2178.     result->tb_next = NULL;
  2179.  
  2180.     Py_INCREF( frame );
  2181.     result->tb_frame  = frame;
  2182.  
  2183.     result->tb_lasti  = 0;
  2184.     result->tb_lineno = line;
  2185.  
  2186.     PyObject_GC_Track( result );
  2187.  
  2188.     return result;
  2189. }
  2190.  
  2191. static void ADD_TRACEBACK( PyObject *module, PyObject *filename, PyObject *function_name, int line )
  2192. {
  2193.     // TODO: The frame object really might deserve a longer life that this, it is
  2194.     // relatively expensive to create.
  2195.     PyFrameObject *frame = MAKE_FRAME( module, filename, function_name, line );
  2196.  
  2197.     // Inlining PyTraceBack_Here may be faster
  2198.     PyTraceBack_Here( frame );
  2199.  
  2200.     Py_DECREF( frame );
  2201. }
  2202.  
  2203.  
  2204. #ifdef _NUITKA_EXE
  2205. static bool FIND_EMBEDDED_MODULE( char const *name );
  2206. #endif
  2207.  
  2208. static PyObject *IMPORT_MODULE( PyObject *module_name, PyObject *import_name )
  2209. {
  2210.  
  2211. #ifdef _NUITKA_EXE
  2212.     // First try our own package resistent form of frozen modules if we have
  2213.     // them embedded. And avoid recursion here too, in case of cyclic dependencies.
  2214.     if ( !HAS_KEY( PySys_GetObject( (char *)"modules" ), module_name ) )
  2215.     {
  2216.         if ( FIND_EMBEDDED_MODULE( PyString_AsString( module_name ) ) )
  2217.         {
  2218.             return LOOKUP_SUBSCRIPT( PySys_GetObject( (char *)"modules" ), import_name );
  2219.         }
  2220.     }
  2221. #endif
  2222.  
  2223.     int line = _current_line;
  2224.  
  2225.     PyObject *result = PyImport_ImportModuleEx( PyString_AsString( module_name ), NULL, NULL, NULL );
  2226.  
  2227.     if (unlikely( result == NULL ))
  2228.     {
  2229.         _current_line = line;
  2230.         throw _PythonException();
  2231.     }
  2232.  
  2233.     // Release the reference returned from the __import__ call, we don't trust it, because
  2234.     // it doesn't work well with packages. Look up in sys.modules instead.
  2235.     Py_DECREF( result );
  2236.  
  2237.     return LOOKUP_SUBSCRIPT( PySys_GetObject( (char *)"modules" ), import_name );
  2238. }
  2239.  
  2240. static void IMPORT_MODULE_STAR( PyObject *target, bool is_module, PyObject *module_name )
  2241. {
  2242.     PyObject *module = IMPORT_MODULE( module_name, module_name );
  2243.  
  2244.     // IMPORT_MODULE would raise exception already
  2245.     assert( module != NULL );
  2246.  
  2247.     PyObject *iter;
  2248.     bool all_case;
  2249.  
  2250.     if ( PyObject *all = PyMapping_GetItemString( module, (char *)"__all__" ) )
  2251.     {
  2252.         iter = MAKE_ITERATOR( all );
  2253.         all_case = true;
  2254.     }
  2255.     else
  2256.     {
  2257.         PyErr_Clear();
  2258.  
  2259.         iter = MAKE_ITERATOR( PyModule_GetDict( module ) );
  2260.         all_case = false;
  2261.     }
  2262.  
  2263.     while ( PyObject *item = PyIter_Next( iter ) )
  2264.     {
  2265.         assert( PyString_Check( item ) );
  2266.  
  2267.         // TODO: Not yet clear, what happens with __all__ and "_" of its contents.
  2268.         if ( all_case == false )
  2269.         {
  2270.             if ( PyString_AS_STRING( item )[0] == '_' )
  2271.             {
  2272.                 continue;
  2273.             }
  2274.         }
  2275.  
  2276.         // TODO: Check if the reference is handled correctly
  2277.         if ( is_module )
  2278.         {
  2279.             SET_ATTRIBUTE( target, item, LOOKUP_ATTRIBUTE( module, item ) );
  2280.         }
  2281.         else
  2282.         {
  2283.             SET_SUBSCRIPT( target, item, LOOKUP_ATTRIBUTE( module, item ) );
  2284.         }
  2285.  
  2286.         Py_DECREF( item );
  2287.     }
  2288.  
  2289.     if ( PyErr_Occurred() )
  2290.     {
  2291.         throw _PythonException();
  2292.     }
  2293. }
  2294.  
  2295.  
  2296. // *** Nuitka_Function type begin
  2297.  
  2298. typedef void (*releaser)( void * );
  2299.  
  2300. // The Nuitka_FunctionObject is the storage associated with a compiled function instance
  2301. // of which there can be many for each code.
  2302. typedef struct {
  2303.     PyObject_HEAD
  2304.  
  2305.     PyObject *m_name;
  2306.  
  2307.     void *m_context;
  2308.     releaser m_cleanup;
  2309.  
  2310.     PyObject *m_module;
  2311.     PyObject *m_doc;
  2312.  
  2313.     void *m_code;
  2314.     bool m_has_args;
  2315.  
  2316.     PyObject *m_dict;
  2317.     PyObject *m_weakrefs;
  2318.  
  2319.     long m_counter;
  2320. } Nuitka_FunctionObject;
  2321.  
  2322. // tp_descr_get slot, bind a function to an object.
  2323. static PyObject *Nuitka_Function_descr_get( PyObject *function, PyObject *object, PyObject *klass )
  2324. {
  2325.     return PyMethod_New( function, object == Py_None ? NULL : object, klass );
  2326. }
  2327.  
  2328.  // tp_repr slot, decide how a function shall be output
  2329. static PyObject *Nuitka_Function_repr( Nuitka_FunctionObject *object )
  2330. {
  2331.     return PyString_FromFormat( "<compiled function %s at %p>", PyString_AsString( object->m_name ), object );
  2332. }
  2333.  
  2334. static PyObject *Nuitka_Function_tp_call( Nuitka_FunctionObject *function, PyObject *args, PyObject *kw )
  2335. {
  2336.     if ( function->m_has_args )
  2337.     {
  2338.        return ((PyCFunctionWithKeywords)function->m_code)( (PyObject *)function->m_context, args, kw );
  2339.     }
  2340.     else
  2341.     {
  2342.        return ((PyNoArgsFunction)function->m_code)( (PyObject *)function->m_context );
  2343.     }
  2344. }
  2345.  
  2346. static long Nuitka_Function_tp_traverse( PyObject *function, visitproc visit, void *arg )
  2347. {
  2348.     // TODO: Identify the impact of not visiting owned objects and/or if it could be NULL
  2349.     // instead. The methodobject visits its self and module. I understand this is probably
  2350.     // so that back references of this function to its upper do not make it stay in the
  2351.     // memory. A specific test if that works might be needed.
  2352.     return 0;
  2353. }
  2354.  
  2355. static int Nuitka_Function_tp_compare( Nuitka_FunctionObject *a, Nuitka_FunctionObject *b )
  2356. {
  2357.     if ( a->m_counter == b->m_counter )
  2358.     {
  2359.        return 0;
  2360.     }
  2361.     else
  2362.     {
  2363.        return a->m_counter < b->m_counter ? -1 : 1;
  2364.     }
  2365. }
  2366.  
  2367. static long Nuitka_Function_tp_hash( Nuitka_FunctionObject *function )
  2368. {
  2369.     return function->m_counter;
  2370. }
  2371.  
  2372. static PyObject *Nuitka_Function_get_name( Nuitka_FunctionObject *object )
  2373. {
  2374.     return INCREASE_REFCOUNT( object->m_name );
  2375. }
  2376.  
  2377. static int Nuitka_Function_set_name( Nuitka_FunctionObject *object, PyObject *value )
  2378. {
  2379.     if (value == NULL || PyString_Check( value ) == 0)
  2380.     {
  2381.        PyErr_Format( PyExc_TypeError, "__name__ must be set to a string object" );
  2382.        return -1;
  2383.     }
  2384.  
  2385.     PyObject *old = object->m_name;
  2386.     Py_DECREF( old );
  2387.     object->m_name = INCREASE_REFCOUNT( value );
  2388.  
  2389.     return 0;
  2390. }
  2391.  
  2392. static PyObject *Nuitka_Function_get_doc( Nuitka_FunctionObject *object )
  2393. {
  2394.     return INCREASE_REFCOUNT( object->m_doc );
  2395. }
  2396.  
  2397. static int Nuitka_Function_set_doc( Nuitka_FunctionObject *object, PyObject *value )
  2398. {
  2399.     if ( value == Py_None || value == NULL )
  2400.     {
  2401.        object->m_doc = Py_None;
  2402.     }
  2403.     else if ( PyString_Check( value ) == 0 )
  2404.     {
  2405.        PyErr_Format( PyExc_TypeError, "__name__ must be set to a string object" );
  2406.        return -1;
  2407.     }
  2408.     else
  2409.     {
  2410.        object->m_doc = INCREASE_REFCOUNT( value );
  2411.     }
  2412.  
  2413.     return 0;
  2414. }
  2415.  
  2416. static PyObject *Nuitka_Function_get_dict( Nuitka_FunctionObject *object )
  2417. {
  2418.    if ( object->m_dict == NULL )
  2419.    {
  2420.       object->m_dict = PyDict_New();
  2421.    }
  2422.  
  2423.    return INCREASE_REFCOUNT( object->m_dict );
  2424. }
  2425.  
  2426. static int Nuitka_Function_set_dict( Nuitka_FunctionObject *object, PyObject *value )
  2427. {
  2428.     if (value == NULL)
  2429.     {
  2430.         PyErr_Format( PyExc_TypeError, "function's dictionary may not be deleted");
  2431.         return -1;
  2432.     }
  2433.  
  2434.     if ( PyDict_Check(value) )
  2435.     {
  2436.         PyObject *old = object->m_dict;
  2437.  
  2438.         object->m_dict = INCREASE_REFCOUNT( value );
  2439.         Py_DECREF( object->m_dict );
  2440.     }
  2441.     else
  2442.     {
  2443.         PyErr_SetString( PyExc_TypeError, "setting function's dictionary to a non-dict" );
  2444.         return -1;
  2445.     }
  2446. }
  2447.  
  2448. static int Nuitka_Function_set_globals( Nuitka_FunctionObject *object, PyObject *value )
  2449. {
  2450.     PyErr_Format( PyExc_TypeError, "readonly attribute" );
  2451.     return -1;
  2452. }
  2453.  
  2454. static PyObject *Nuitka_Function_get_globals( Nuitka_FunctionObject *object )
  2455. {
  2456.     return INCREASE_REFCOUNT( PyModule_GetDict( object->m_module ) );
  2457. }
  2458.  
  2459. static int Nuitka_Function_set_module( Nuitka_FunctionObject *object, PyObject *value )
  2460. {
  2461.     if ( object->m_dict == NULL )
  2462.     {
  2463.        object->m_dict = PyDict_New();
  2464.     }
  2465.  
  2466.     return PyDict_SetItemString( object->m_dict, (char * )"__module__", value );
  2467. }
  2468.  
  2469. static PyObject *Nuitka_Function_get_module( Nuitka_FunctionObject *object )
  2470. {
  2471.     if ( object->m_dict )
  2472.     {
  2473.         PyObject *result = PyDict_GetItemString( object->m_dict, (char * )"__module__" );
  2474.  
  2475.         if ( result != NULL )
  2476.         {
  2477.             return INCREASE_REFCOUNT( result );
  2478.         }
  2479.     }
  2480.  
  2481.     int res = Nuitka_Function_set_module( object, PyString_FromString( PyModule_GetName( object->m_module ) ) );
  2482.  
  2483.     assert( res == 0 );
  2484.  
  2485.     return PyDict_GetItemString( object->m_dict, (char * )"__module__" );
  2486. }
  2487.  
  2488.  
  2489. static PyGetSetDef Nuitka_Function_getset[] =
  2490. {
  2491.    { (char *)"func_name",    (getter)Nuitka_Function_get_name,    (setter)Nuitka_Function_set_name, NULL },
  2492.    { (char *)"__name__" ,    (getter)Nuitka_Function_get_name,    (setter)Nuitka_Function_set_name, NULL },
  2493.    { (char *)"func_doc",     (getter)Nuitka_Function_get_doc,     (setter)Nuitka_Function_set_doc, NULL },
  2494.    { (char *)"__doc__" ,     (getter)Nuitka_Function_get_doc,     (setter)Nuitka_Function_set_doc, NULL },
  2495.    { (char *)"func_dict",    (getter)Nuitka_Function_get_dict,    (setter)Nuitka_Function_set_dict, NULL },
  2496.    { (char *)"__dict__",     (getter)Nuitka_Function_get_dict,    (setter)Nuitka_Function_set_dict, NULL },
  2497.    { (char *)"func_globals", (getter)Nuitka_Function_get_globals, (setter)Nuitka_Function_set_globals, NULL },
  2498.    { (char *)"__globals__",  (getter)Nuitka_Function_get_globals, (setter)Nuitka_Function_set_globals, NULL },
  2499.    { (char *)"__module__",   (getter)Nuitka_Function_get_module,  (setter)Nuitka_Function_set_module, NULL },
  2500.    { NULL }
  2501. };
  2502.  
  2503.  
  2504. static void Nuitka_Function_tp_dealloc( Nuitka_FunctionObject *function )
  2505. {
  2506.     _PyObject_GC_UNTRACK( function );
  2507.  
  2508.     if ( function->m_weakrefs != NULL )
  2509.     {
  2510.         PyObject_ClearWeakRefs( (PyObject *)function );
  2511.     }
  2512.  
  2513.     Py_DECREF( function->m_name );
  2514.     Py_XDECREF( function->m_dict );
  2515.  
  2516.     if ( function->m_context )
  2517.     {
  2518.         function->m_cleanup( function->m_context );
  2519.     }
  2520.  
  2521.     PyObject_GC_Del( function );
  2522. }
  2523.  
  2524. static PyTypeObject Nuitka_Function_Type =
  2525. {
  2526.     PyVarObject_HEAD_INIT(&PyType_Type, 0)
  2527.     "compiled_function_or_method",                  // tp_name
  2528.     sizeof(Nuitka_FunctionObject),                  // tp_basicsize
  2529.     0,                                              // tp_itemsize
  2530.     (destructor)Nuitka_Function_tp_dealloc,         // tp_dealloc
  2531.     0,                                              // tp_print
  2532.     0,                                              // tp_getattr
  2533.     0,                                              // tp_setattr
  2534.     (cmpfunc)Nuitka_Function_tp_compare,            // tp_compare
  2535.     (reprfunc)Nuitka_Function_repr,                 // tp_repr
  2536.     0,                                              // tp_as_number
  2537.     0,                                              // tp_as_sequence
  2538.     0,                                              // tp_as_mapping
  2539.     (hashfunc)Nuitka_Function_tp_hash,              // tp_hash
  2540.     (ternaryfunc)Nuitka_Function_tp_call,           // tp_call
  2541.     0,                                              // tp_str
  2542.     PyObject_GenericGetAttr,                        // tp_getattro
  2543.     0,                                              // tp_setattro
  2544.     0,                                              // tp_as_buffer
  2545.     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,        // tp_flags
  2546.     0,                                              // tp_doc
  2547.     (traverseproc)Nuitka_Function_tp_traverse,      // tp_traverse
  2548.     0,                                              // tp_clear
  2549.     0,                                              // tp_richcompare
  2550.     offsetof( Nuitka_FunctionObject, m_weakrefs ),  // tp_weaklistoffset
  2551.     0,                                              // tp_iter
  2552.     0,                                              // tp_iternext
  2553.     0,                                              // tp_methods
  2554.     0,                                              // tp_members
  2555.     Nuitka_Function_getset,                         // tp_getset
  2556.     0,                                              // tp_base
  2557.     0,                                              // tp_dict
  2558.     Nuitka_Function_descr_get,                      // tp_descr_get
  2559.     0,                                              // tp_descr_set
  2560.     offsetof( Nuitka_FunctionObject, m_dict ),      // tp_dictoffset
  2561.     0,                                              // tp_init
  2562.     0,                                              // tp_alloc
  2563.     0,                                              // tp_new
  2564.     0,                                              // tp_free
  2565.     0,                                              // tp_is_gc
  2566.     0,                                              // tp_bases
  2567.     0,                                              // tp_mro
  2568.     0,                                              // tp_cache
  2569.     0,                                              // tp_subclasses
  2570.     0,                                              // tp_weaklist
  2571.     0,                                              // tp_del
  2572. };
  2573.  
  2574. static inline PyObject *make_kfunction( void *code, PyObject *name, PyObject *module, PyObject *doc, bool has_args, void *context, releaser cleanup )
  2575. {
  2576.     Nuitka_FunctionObject *result = PyObject_GC_New( Nuitka_FunctionObject, &Nuitka_Function_Type );
  2577.  
  2578.     if ( result == NULL )
  2579.     {
  2580.         PyErr_Format( PyExc_RuntimeError, "cannot create function %s", PyString_AsString( name ) );
  2581.         throw _PythonException();
  2582.     }
  2583.  
  2584.     result->m_code = code;
  2585.     result->m_has_args = has_args;
  2586.  
  2587.     result->m_name = INCREASE_REFCOUNT( name );
  2588.  
  2589.     result->m_context = context;
  2590.     result->m_cleanup = cleanup;
  2591.  
  2592.     result->m_module = module;
  2593.     result->m_doc    = doc;
  2594.     result->m_dict   = NULL;
  2595.  
  2596.     result->m_weakrefs = NULL;
  2597.  
  2598.     static long Nuitka_Function_counter = 0;
  2599.     result->m_counter = Nuitka_Function_counter++;
  2600.  
  2601.     _PyObject_GC_TRACK( result );
  2602.     return (PyObject *)result;
  2603. }
  2604.  
  2605. // Make a function without context.
  2606. static PyObject *Nuitka_Function_New( PyCFunctionWithKeywords code, PyObject *name, PyObject *module, PyObject *doc )
  2607. {
  2608.     return make_kfunction( (void *)code, name, module, doc, true, NULL, NULL );
  2609. }
  2610.  
  2611. // Make a function with context.
  2612.  
  2613. static PyObject *Nuitka_Function_New( PyCFunctionWithKeywords code, PyObject *name, PyObject *module, PyObject *doc, void *context, releaser cleanup )
  2614. {
  2615.     return make_kfunction( (void *)code, name, module, doc, true, context, cleanup );
  2616. }
  2617.  
  2618. // Make a function that is only a yielder, no args.
  2619. static PyObject *Nuitka_Function_New( PyNoArgsFunction code, PyObject *name, PyObject *module, PyObject *doc, void *context, releaser cleanup )
  2620. {
  2621.     return make_kfunction( (void *)code, name, module, doc, false, context, cleanup );
  2622. }
  2623.  
  2624. // *** KFunction type end
  2625.  
  2626.  
  2627.  
  2628. // *** Nuitka_Generator/Nuitka_Genexpr shared begin
  2629.  
  2630. enum class Generator_Status {
  2631.     status_Unused,  // Not used so far
  2632.     status_Running, // Running, used but didn't stop yet
  2633.     status_Finished // Stoped, no more values to come
  2634. };
  2635.  
  2636. // *** Nuitka_Generator type begin
  2637.  
  2638. #include <ucontext.h>
  2639.  
  2640. // The Nuitka_GeneratorObject is the storage associated with a compiled generator object
  2641. // instance of which there can be many for each code.
  2642. typedef struct {
  2643.     PyObject_HEAD
  2644.  
  2645.     PyObject *m_name;
  2646.  
  2647.     ucontext_t m_yielder_context;
  2648.     ucontext_t m_caller_context;
  2649.  
  2650.     void *m_context;
  2651.     releaser m_cleanup;
  2652.  
  2653.     // TODO: Clarify if weakrefs are supported for generator objects in CPython.
  2654.     PyObject *m_weakrefs;
  2655.  
  2656.     bool m_running;
  2657.  
  2658.     void *m_code;
  2659.  
  2660.     PyObject *m_yielded;
  2661.     PyObject *m_exception_type, *m_exception_value, *m_exception_tb;
  2662.  
  2663.     // Was it ever used, is it still running, or already finished.
  2664.     Generator_Status m_status;
  2665.  
  2666. } Nuitka_GeneratorObject;
  2667.  
  2668.  
  2669. static PyObject *Nuitka_Generator_tp_repr( Nuitka_GeneratorObject *generator )
  2670. {
  2671.     return PyString_FromFormat( "<compiled generator object %s at %p>", PyString_AsString( generator->m_name ), generator );
  2672. }
  2673.  
  2674. static long Nuitka_Generator_tp_traverse( PyObject *function, visitproc visit, void *arg )
  2675. {
  2676.     // TODO: Identify the impact of not visiting owned objects and/or if it could be NULL
  2677.     // instead. The methodobject visits its self and module. I understand this is probably
  2678.     // so that back references of this function to its upper do not make it stay in the
  2679.     // memory. A specific test if that works might be needed.
  2680.     return 0;
  2681. }
  2682.  
  2683.  
  2684. static PyObject *Nuitka_Generator_send( Nuitka_GeneratorObject *generator, PyObject *value )
  2685. {
  2686.     if ( generator->m_status == Generator_Status::status_Unused && value != NULL && value != Py_None )
  2687.     {
  2688.         PyErr_Format( PyExc_TypeError, "can't send non-None value to a just-started generator" );
  2689.         return NULL;
  2690.     }
  2691.  
  2692.     if ( generator->m_status != Generator_Status::status_Finished )
  2693.     {
  2694.         if ( generator->m_running )
  2695.         {
  2696.             PyErr_Format( PyExc_ValueError, "generator already executing" );
  2697.             return NULL;
  2698.         }
  2699.  
  2700.         if ( generator->m_status == Generator_Status::status_Unused )
  2701.         {
  2702.             generator->m_status = Generator_Status::status_Running;
  2703.  
  2704.             // Prepare the generator context to run. TODO: Make stack size rational.
  2705.             generator->m_yielder_context.uc_stack.ss_size = 1024*1024;
  2706.             generator->m_yielder_context.uc_stack.ss_sp = malloc( generator->m_yielder_context.uc_stack.ss_size );
  2707.  
  2708.             getcontext( &generator->m_yielder_context );
  2709.             makecontext( &generator->m_yielder_context, (void (*)())generator->m_code, 1, generator );
  2710.         }
  2711.  
  2712.         generator->m_yielded = value;
  2713.  
  2714.         generator->m_running = true;
  2715.  
  2716.         // Continue the yielder function.
  2717.         swapcontext( &generator->m_caller_context, &generator->m_yielder_context );
  2718.  
  2719.         generator->m_running = false;
  2720.  
  2721.         if ( generator->m_yielded == NULL )
  2722.         {
  2723.             generator->m_status = Generator_Status::status_Finished;
  2724.  
  2725.             return NULL;
  2726.         }
  2727.         else
  2728.         {
  2729.             return generator->m_yielded;
  2730.         }
  2731.     }
  2732.     else
  2733.     {
  2734.         PyErr_SetNone( PyExc_StopIteration );
  2735.         return NULL;
  2736.     }
  2737. }
  2738.  
  2739. static PyObject *Nuitka_Generator_tp_iternext( Nuitka_GeneratorObject *generator )
  2740. {
  2741.     return Nuitka_Generator_send( generator, Py_None );
  2742. }
  2743.  
  2744.  
  2745. static PyObject *Nuitka_Generator_close( Nuitka_GeneratorObject *generator, PyObject *args )
  2746. {
  2747.     if ( generator->m_status != Generator_Status::status_Finished )
  2748.     {
  2749.         generator->m_exception_type = PyExc_GeneratorExit;
  2750.         generator->m_exception_value = NULL;
  2751.         generator->m_exception_tb = NULL;
  2752.  
  2753.         PyObject *result = Nuitka_Generator_send( generator, Py_None );
  2754.  
  2755.         if (!( result == NULL || PyErr_ExceptionMatches( PyExc_StopIteration ) || PyErr_ExceptionMatches( PyExc_GeneratorExit )))
  2756.         {
  2757.             Py_XDECREF( result );
  2758.  
  2759.             PyErr_Format( PyExc_RuntimeError, "generator refused GeneratorExit" );
  2760.             return NULL;
  2761.         }
  2762.  
  2763.         PyErr_Clear();
  2764.     }
  2765.  
  2766.     return INCREASE_REFCOUNT( Py_None );
  2767. }
  2768.  
  2769. static void Nuitka_Generator_tp_dealloc( Nuitka_GeneratorObject *generator )
  2770. {
  2771.     assert( generator->ob_refcnt == 0 );
  2772.     generator->ob_refcnt = 1;
  2773.  
  2774.     PyObject *close_result = Nuitka_Generator_close( generator, NULL );
  2775.     Py_XDECREF( close_result );
  2776.  
  2777.     assert( generator->ob_refcnt == 1 );
  2778.     generator->ob_refcnt = 0;
  2779.  
  2780.     free( generator->m_yielder_context.uc_stack.ss_sp );
  2781.  
  2782.     // Now it is safe to release references and memory for it.
  2783.     _PyObject_GC_UNTRACK( generator );
  2784.  
  2785.     if ( generator->m_weakrefs != NULL )
  2786.     {
  2787.         PyObject_ClearWeakRefs( (PyObject *)generator );
  2788.     }
  2789.  
  2790.     if ( generator->m_context )
  2791.     {
  2792.         generator->m_cleanup( generator->m_context );
  2793.     }
  2794.  
  2795.     Py_DECREF( generator->m_name );
  2796.  
  2797.     PyObject_GC_Del( generator );
  2798. }
  2799.  
  2800. static PyObject *Nuitka_Generator_throw( Nuitka_GeneratorObject *generator, PyObject *args )
  2801. {
  2802.     generator->m_exception_value = NULL;
  2803.     generator->m_exception_tb = NULL;
  2804.  
  2805.     int res = PyArg_UnpackTuple( args, "throw", 1, 3, &generator->m_exception_type, &generator->m_exception_value, &generator->m_exception_tb );
  2806.  
  2807.     if ( res == 0 )
  2808.     {
  2809.         generator->m_exception_type = NULL;
  2810.  
  2811.         return NULL;
  2812.     }
  2813.  
  2814.     if ( generator->m_status != Generator_Status::status_Finished )
  2815.     {
  2816.         return Nuitka_Generator_send( generator, Py_None );
  2817.     }
  2818.     else
  2819.     {
  2820.         return Py_None;
  2821.     }
  2822. }
  2823.  
  2824. static PyObject *Nuitka_Generator_get_name( Nuitka_GeneratorObject *generator )
  2825. {
  2826.     return INCREASE_REFCOUNT( generator->m_name );
  2827. }
  2828.  
  2829. static PyGetSetDef Nuitka_Generator_getsetlist[] =
  2830. {
  2831.     { (char * )"__name__", (getter)Nuitka_Generator_get_name, NULL, NULL },
  2832.     { NULL }
  2833. };
  2834.  
  2835. static PyMethodDef Nuitka_Generator_methods[] =
  2836. {
  2837.     { "send", (PyCFunction)Nuitka_Generator_send,  METH_O, NULL },
  2838.     {"throw", (PyCFunction)Nuitka_Generator_throw, METH_VARARGS, NULL },
  2839.     {"close", (PyCFunction)Nuitka_Generator_close, METH_NOARGS, NULL },
  2840.     { NULL }
  2841. };
  2842.  
  2843. static PyTypeObject Nuitka_Generator_Type =
  2844. {
  2845.     PyVarObject_HEAD_INIT(&PyType_Type, 0)
  2846.     "compiled_generator",                            // tp_name
  2847.     sizeof(Nuitka_GeneratorObject),                  // tp_basicsize
  2848.     0,                                               // tp_itemsize
  2849.     (destructor)Nuitka_Generator_tp_dealloc,         // tp_dealloc
  2850.     0,                                               // tp_print
  2851.     0,                                               // tp_getattr
  2852.     0,                                               // tp_setattr
  2853.     // TODO: Compare should be easy, check the benefit of doing it.
  2854.     0,                                               // tp_compare
  2855.     (reprfunc)Nuitka_Generator_tp_repr,              // tp_repr
  2856.     0,                                               // tp_as_number
  2857.     0,                                               // tp_as_sequence
  2858.     0,                                               // tp_as_mapping
  2859.     0,                                               // tp_hash
  2860.     0,                                               // tp_call
  2861.     0,                                               // tp_str
  2862.     PyObject_GenericGetAttr,                         // tp_getattro
  2863.     0,                                               // tp_setattro
  2864.     0,                                               // tp_as_buffer
  2865.     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,         // tp_flags
  2866.     0,                                               // tp_doc
  2867.     (traverseproc)Nuitka_Generator_tp_traverse,      // tp_traverse
  2868.     0,                                               // tp_clear
  2869.     0,                                               // tp_richcompare
  2870.     offsetof( Nuitka_GeneratorObject, m_weakrefs ),  // tp_weaklistoffset
  2871.     PyObject_SelfIter,                               // tp_iter
  2872.     (iternextfunc)Nuitka_Generator_tp_iternext,      // tp_iternext
  2873.     Nuitka_Generator_methods,                        // tp_methods
  2874.     0,                                               // tp_members
  2875.     Nuitka_Generator_getsetlist,                     // tp_getset
  2876.     0,                                               // tp_base
  2877.     0,                                               // tp_dict
  2878.     0,                                               // tp_descr_get
  2879.     0,                                               // tp_descr_set
  2880.     0,                                               // tp_dictoffset
  2881.     0,                                               // tp_init
  2882.     0,                                               // tp_alloc
  2883.     0,                                               // tp_new
  2884.     0,                                               // tp_free
  2885.     0,                                               // tp_is_gc
  2886.     0,                                               // tp_bases
  2887.     0,                                               // tp_mro
  2888.     0,                                               // tp_cache
  2889.     0,                                               // tp_subclasses
  2890.     0,                                               // tp_weaklist
  2891.     0                                                // tp_del
  2892. };
  2893.  
  2894. typedef void (*yielder_func)( Nuitka_GeneratorObject * );
  2895.  
  2896. static PyObject *Nuitka_Generator_New( yielder_func code, PyObject *name, void *context, releaser cleanup )
  2897. {
  2898.     Nuitka_GeneratorObject *result = PyObject_GC_New( Nuitka_GeneratorObject, &Nuitka_Generator_Type );
  2899.  
  2900.     if ( result == NULL )
  2901.     {
  2902.         PyErr_Format( PyExc_RuntimeError, "cannot create genexpr %s", PyString_AsString( name ) );
  2903.         throw _PythonException();
  2904.     }
  2905.  
  2906.     result->m_code = (void *)code;
  2907.  
  2908.     result->m_name = INCREASE_REFCOUNT( name );
  2909.  
  2910.     result->m_context = context;
  2911.     result->m_cleanup = cleanup;
  2912.  
  2913.     result->m_weakrefs = NULL;
  2914.  
  2915.     result->m_status = Generator_Status::status_Unused;
  2916.     result->m_running = false;
  2917.  
  2918.     result->m_yielder_context.uc_stack.ss_sp = NULL;
  2919.     result->m_yielder_context.uc_link = NULL;
  2920.  
  2921.     result->m_exception_type = NULL;
  2922.  
  2923.     _PyObject_GC_TRACK( result );
  2924.     return (PyObject *)result;
  2925. }
  2926.  
  2927. static void CHECK_EXCEPTION( Nuitka_GeneratorObject *generator )
  2928. {
  2929.     if ( generator->m_exception_type )
  2930.     {
  2931.         Py_INCREF( generator->m_exception_type );
  2932.         Py_XINCREF( generator->m_exception_value );
  2933.         Py_XINCREF( generator->m_exception_tb );
  2934.  
  2935.         PyErr_Restore( generator->m_exception_type, generator->m_exception_value, generator->m_exception_tb );
  2936.         generator->m_exception_type = NULL;
  2937.  
  2938.         throw _PythonException();
  2939.     }
  2940. }
  2941.  
  2942. static PyObject *YIELD_VALUE( Nuitka_GeneratorObject *generator, PyObject *value )
  2943. {
  2944.     generator->m_yielded = value;
  2945.  
  2946.     swapcontext( &generator->m_yielder_context, &generator->m_caller_context );
  2947.  
  2948.     CHECK_EXCEPTION( generator );
  2949.  
  2950.     return generator->m_yielded;
  2951. }
  2952.  
  2953. // *** Nuitka_Generator type end
  2954.  
  2955.  
  2956.  
  2957. // *** Nuitka_Genexpr type begin
  2958.  
  2959. // TODO: Could optimize it through a compile time determination.
  2960. const int MAX_ITERATOR_COUNT = 20;
  2961.  
  2962. // The Nuitka_GenexprObject is the storage associated with a compiled generator object
  2963. // instance of which there can be many for each code.
  2964. typedef struct {
  2965.     PyObject_HEAD
  2966.  
  2967.     PyObject *m_name;
  2968.  
  2969.     void *m_context;
  2970.     releaser m_cleanup;
  2971.  
  2972.     PyObject *m_weakrefs;
  2973.  
  2974.     bool m_running;
  2975.     void *m_code;
  2976.  
  2977.     // Was it ever used, is it still running, or already finished.
  2978.     Generator_Status m_status;
  2979.  
  2980.     // Store the iterator provided at creation time here.
  2981.     PyObject *iterators[ MAX_ITERATOR_COUNT ];
  2982.  
  2983.     int iterator_level;
  2984.  
  2985. } Nuitka_GenexprObject;
  2986.  
  2987. typedef PyObject * (*producer)( Nuitka_GenexprObject * );
  2988.  
  2989. static PyObject *Nuitka_Genexpr_tp_repr( Nuitka_GenexprObject *generator )
  2990. {
  2991.     return PyString_FromFormat( "<compiled generator object <%s> at %p>", PyString_AsString( generator->m_name ), generator );
  2992. }
  2993.  
  2994. static long Nuitka_Genexpr_tp_traverse( PyObject *function, visitproc visit, void *arg )
  2995. {
  2996.     // TODO: Identify the impact of not visiting owned objects and/or if it could be NULL
  2997.     // instead. The methodobject visits its self and module. I understand this is probably
  2998.     // so that back references of this function to its upper do not make it stay in the
  2999.     // memory. A specific test if that works might be needed.
  3000.     return 0;
  3001. }
  3002.  
  3003. static void Nuitka_Genexpr_tp_dealloc( Nuitka_GenexprObject *generator )
  3004. {
  3005.     // Now it is safe to release references and memory for it.
  3006.     _PyObject_GC_UNTRACK( generator );
  3007.  
  3008.     if ( generator->m_weakrefs != NULL )
  3009.     {
  3010.         PyObject_ClearWeakRefs( (PyObject *)generator );
  3011.     }
  3012.  
  3013.     if ( generator->m_context )
  3014.     {
  3015.         generator->m_cleanup( generator->m_context );
  3016.     }
  3017.  
  3018.     Py_DECREF( generator->m_name );
  3019.  
  3020.     for( int i = 0; i <= generator->iterator_level; i++ )
  3021.     {
  3022.         if ( generator->iterators[ i ] )
  3023.         {
  3024.             Py_DECREF( generator->iterators[ i ] );
  3025.         }
  3026.     }
  3027.  
  3028.     PyObject_GC_Del( generator );
  3029. }
  3030.  
  3031. static PyObject *Nuitka_Genexpr_tp_iternext( Nuitka_GenexprObject *generator )
  3032. {
  3033.     if ( generator->m_status != Generator_Status::status_Finished )
  3034.     {
  3035.         if ( generator->m_running )
  3036.         {
  3037.             PyErr_Format( PyExc_ValueError, "generator already executing" );
  3038.             return NULL;
  3039.         }
  3040.  
  3041.         generator->m_running = true;
  3042.  
  3043.         // Query the next value
  3044.         PyObject *result = ((producer)(generator->m_code))( generator );
  3045.  
  3046.         generator->m_running = false;
  3047.  
  3048.         if ( result == _sentinel_value )
  3049.         {
  3050.             generator->m_status = Generator_Status::status_Finished;
  3051.  
  3052.             PyErr_SetNone( PyExc_StopIteration );
  3053.             return NULL;
  3054.         }
  3055.         else
  3056.         {
  3057.             if ( result )
  3058.             {
  3059.                 generator->m_status = Generator_Status::status_Running;
  3060.             }
  3061.             else
  3062.             {
  3063.                 generator->m_status = Generator_Status::status_Finished;
  3064.             }
  3065.  
  3066.             return result;
  3067.         }
  3068.     }
  3069.     else
  3070.     {
  3071.         PyErr_SetNone( PyExc_StopIteration );
  3072.         return NULL;
  3073.     }
  3074. }
  3075.  
  3076. static PyObject *Nuitka_Genexpr_send( Nuitka_GenexprObject *generator, PyObject *value )
  3077. {
  3078.     if ( generator->m_status == Generator_Status::status_Unused && value != NULL && value != Py_None )
  3079.     {
  3080.         PyErr_Format( PyExc_TypeError, "can't send non-None value to a just-started generator" );
  3081.         return NULL;
  3082.     }
  3083.  
  3084.     return Nuitka_Genexpr_tp_iternext( generator );
  3085. }
  3086.  
  3087. static PyObject *Nuitka_Genexpr_close( Nuitka_GenexprObject *generator, PyObject *args )
  3088. {
  3089.     generator->m_status = Generator_Status::status_Finished;
  3090.     return INCREASE_REFCOUNT( Py_None );
  3091. }
  3092.  
  3093. static PyObject *Nuitka_Genexpr_throw( Nuitka_GenexprObject *generator, PyObject *args )
  3094. {
  3095.     PyObject *exception_type, *exception_value, *exception_tb;
  3096.  
  3097.     int res = PyArg_UnpackTuple( args, "throw", 1, 3, &exception_type, &exception_value, &exception_tb );
  3098.  
  3099.     if ( res == 0 )
  3100.     {
  3101.         return NULL;
  3102.     }
  3103.  
  3104.     PyErr_Restore( exception_type, exception_value, exception_tb );
  3105.     generator->m_status = Generator_Status::status_Finished;
  3106.  
  3107.     return NULL;
  3108. }
  3109.  
  3110. static PyObject *Nuitka_Genexpr_get_name( Nuitka_GenexprObject *generator )
  3111. {
  3112.     return INCREASE_REFCOUNT( generator->m_name );
  3113. }
  3114.  
  3115. static PyGetSetDef Nuitka_Genexpr_getsetlist[] =
  3116. {
  3117.     { (char * )"__name__", (getter)Nuitka_Genexpr_get_name, NULL, NULL },
  3118.     { NULL }
  3119. };
  3120.  
  3121. static PyMethodDef Nuitka_Genexpr_methods[] =
  3122. {
  3123.     { "send", (PyCFunction)Nuitka_Genexpr_send,  METH_O, NULL },
  3124.     {"throw", (PyCFunction)Nuitka_Genexpr_throw, METH_VARARGS, NULL },
  3125.     {"close", (PyCFunction)Nuitka_Genexpr_close, METH_NOARGS, NULL },
  3126.     { NULL }
  3127. };
  3128.  
  3129. static PyTypeObject Nuitka_Genexpr_Type =
  3130. {
  3131.     PyVarObject_HEAD_INIT(&PyType_Type, 0)
  3132.     "compiled_generator",                          // tp_name
  3133.     sizeof(Nuitka_GenexprObject),                  // tp_basicsize
  3134.     0,                                             // tp_itemsize
  3135.     (destructor)Nuitka_Genexpr_tp_dealloc,         // tp_dealloc
  3136.     0,                                             // tp_print
  3137.     0,                                             // tp_getattr
  3138.     0,                                             // tp_setattr
  3139.     // TODO: Compare should be easy, check the benefit of doing it.
  3140.     0,                                             // tp_compare
  3141.     (reprfunc)Nuitka_Genexpr_tp_repr,              // tp_repr
  3142.     0,                                             // tp_as_number
  3143.     0,                                             // tp_as_sequence
  3144.     0,                                             // tp_as_mapping
  3145.     0,                                             // tp_hash
  3146.     0,                                             // tp_call
  3147.     0,                                             // tp_str
  3148.     PyObject_GenericGetAttr,                       // tp_getattro
  3149.     0,                                             // tp_setattro
  3150.     0,                                             // tp_as_buffer
  3151.     Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,       // tp_flags
  3152.     0,                                             // tp_doc
  3153.     (traverseproc)Nuitka_Genexpr_tp_traverse,      // tp_traverse
  3154.     0,                                             // tp_clear
  3155.     0,                                             // tp_richcompare
  3156.     offsetof( Nuitka_GenexprObject, m_weakrefs ),  // tp_weaklistoffset
  3157.     PyObject_SelfIter,                             // tp_iter
  3158.     (iternextfunc)Nuitka_Genexpr_tp_iternext,      // tp_iternext
  3159.     Nuitka_Genexpr_methods,                        // tp_methods
  3160.     0,                                             // tp_members
  3161.     Nuitka_Genexpr_getsetlist,                     // tp_getset
  3162.     0,                                             // tp_base
  3163.     0,                                             // tp_dict
  3164.     0,                                             // tp_descr_get
  3165.     0,                                             // tp_descr_set
  3166.     0                                       ,      // tp_dictoffset
  3167.     0,                                             // tp_init
  3168.     0,                                             // tp_alloc
  3169.     0,                                             // tp_new
  3170.     0,                                             // tp_free
  3171.     0,                                             // tp_is_gc
  3172.     0,                                             // tp_bases
  3173.     0,                                             // tp_mro
  3174.     0,                                             // tp_cache
  3175.     0,                                             // tp_subclasses
  3176.     0,                                             // tp_weaklist
  3177.     0                                              // tp_del
  3178. };
  3179.  
  3180. static PyObject *Nuitka_Genexpr_New( producer code, PyObject *name, PyObject *iterated, int iterator_count, void *context, releaser cleanup )
  3181. {
  3182.     Nuitka_GenexprObject *result = PyObject_GC_New( Nuitka_GenexprObject, &Nuitka_Genexpr_Type );
  3183.  
  3184.     if ( result == NULL )
  3185.     {
  3186.         PyErr_Format( PyExc_RuntimeError, "cannot create genexpr %s", PyString_AsString( name ) );
  3187.         throw _PythonException();
  3188.     }
  3189.  
  3190.     result->m_code = (void *)code;
  3191.  
  3192.     result->m_name = INCREASE_REFCOUNT( name );
  3193.  
  3194.     result->m_context = context;
  3195.     result->m_cleanup = cleanup;
  3196.  
  3197.     result->m_weakrefs = NULL;
  3198.  
  3199.     result->m_status = Generator_Status::status_Unused;
  3200.     result->m_running = false;
  3201.  
  3202.     // Store the iterator information provided at creation time here.
  3203.     assert( iterator_count < MAX_ITERATOR_COUNT );
  3204.  
  3205.     result->iterator_level = 0;
  3206.     result->iterators[ 0 ] = MAKE_ITERATOR( iterated );
  3207.  
  3208.     for( int i = 1; i < iterator_count; i++ )
  3209.     {
  3210.         result->iterators[ i ] = NULL;
  3211.     }
  3212.  
  3213.     _PyObject_GC_TRACK( result );
  3214.     return (PyObject *)result;
  3215. }
  3216.  
  3217. // *** Nuitka_Genexpr type end
  3218.  
  3219.  
  3220. // The _module___main__ is a Python object pointer  of module type.
  3221.  
  3222. // Note: For full compatability with CPython, every module variable access needs to go
  3223. // through it except for cases where the module cannot possibly have changed in the mean
  3224. // time.
  3225.  
  3226. static PyObject *_module___main__;
  3227.  
  3228. // The module level variables.
  3229. static PyObjectGlobalVariable _mvar___main_____doc__( &_module___main__, &_python_str_plain___doc__ );
  3230. static PyObjectGlobalVariable _mvar___main_____file__( &_module___main__, &_python_str_plain___file__ );
  3231. static PyObjectGlobalVariable _mvar___main___all( &_module___main__, &_python_str_plain_all );
  3232. static PyObjectGlobalVariable _mvar___main___i( &_module___main__, &_python_str_plain_i );
  3233. static PyObjectGlobalVariable _mvar___main___int( &_module___main__, &_python_str_plain_int );
  3234. static PyObjectGlobalVariable _mvar___main___math( &_module___main__, &_python_str_plain_math );
  3235. static PyObjectGlobalVariable _mvar___main___num_primes( &_module___main__, &_python_str_plain_num_primes );
  3236. static PyObjectGlobalVariable _mvar___main___xrange( &_module___main__, &_python_str_plain_xrange );
  3237.  
  3238. // The module function declarations.
  3239. static PyObject *MAKE_FUNCTION_genexpr_1_of_module_hello( PyObject *iterator );
  3240.  
  3241.  
  3242. // The module function definitions.
  3243.  
  3244.  
  3245. // This structure is for attachment as self of genexpr_1_of_module_hello.
  3246. // It is allocated at the time the genexpr object is created.
  3247. struct _context_genexpr_1_of_module_hello_t
  3248. {
  3249.     // The generator expression can access a read-only closure of the creator.
  3250.     PyObjectLocalVariable python_var_j;
  3251.     PyObjectLocalVariable python_var_i;
  3252. };
  3253.  
  3254. static void _context_genexpr_1_of_module_hello_destructor( void *context_voidptr )
  3255. {
  3256.     _context_genexpr_1_of_module_hello_t *_python_context = (struct _context_genexpr_1_of_module_hello_t *)context_voidptr;
  3257.  
  3258.    
  3259.  
  3260.     delete _python_context;
  3261. }
  3262.  
  3263. // The function that is iterated over during generator expression execution. It is supposed to yield the next
  3264. // value as a return value.
  3265.  
  3266. static PyObject *genexpr_1_of_module_hello( Nuitka_GenexprObject *generator )
  3267. {
  3268.     // The context of the genexpr.
  3269.     struct _context_genexpr_1_of_module_hello_t *_python_context = (struct _context_genexpr_1_of_module_hello_t *)generator->m_context;
  3270.  
  3271.     _current_line = 5;
  3272.  
  3273.  
  3274.     try
  3275.     {
  3276.         while ( generator->iterator_level != -1 && generator->iterator_level < 1 )
  3277.         {
  3278.             if ( generator->iterators[ generator->iterator_level ] == NULL )
  3279.             {
  3280.                 switch( generator->iterator_level )
  3281.                 {
  3282.                    case 0:
  3283.                        assert( false );
  3284.                        break;
  3285.                    
  3286.                 }
  3287.             }
  3288.  
  3289.             // Need to construct the iterators except level 0 here and create their iterator
  3290.             // if it is NULL
  3291.  
  3292.             PyObject *_python_genexpr_iter_value = ITERATOR_NEXT( generator->iterators[ generator->iterator_level ] );
  3293.  
  3294.             if ( _python_genexpr_iter_value == NULL )
  3295.             {
  3296.                 Py_DECREF( generator->iterators[ generator->iterator_level ] );
  3297.                 generator->iterators[ generator->iterator_level ] = NULL;
  3298.  
  3299.                 generator->iterator_level -= 1;
  3300.             }
  3301.             else
  3302.             {
  3303.                 bool condition;
  3304.  
  3305.                 switch( generator->iterator_level )
  3306.                 {
  3307.                    
  3308. case 0:
  3309. _python_context->python_var_j = INCREASE_REFCOUNT( _python_genexpr_iter_value );
  3310. condition = true;
  3311.    break;
  3312.  
  3313.                 }
  3314.  
  3315.                 // plug condition here, just don't increase if it mismatches
  3316.                 if ( condition )
  3317.                 {
  3318.                     generator->iterator_level += 1;
  3319.                 }
  3320.             }
  3321.         }
  3322.  
  3323.         if ( generator->iterator_level == -1 )
  3324.         {
  3325.             return _sentinel_value;
  3326.         }
  3327.         else
  3328.         {
  3329.             generator->iterator_level = 1 - 1;
  3330.  
  3331.             // Actual expressions generated.
  3332.             return BINARY_OPERATION( PyNumber_Remainder, PyObjectTemporary( _mvar___main___i.asObject() ).asObject(), _python_context->python_var_j.asObject() );
  3333.         }
  3334.     }
  3335.     catch ( _PythonException &_exception )
  3336.     {
  3337.         _exception.toPython();
  3338.         ADD_TRACEBACK( _module___main__, _python_str_digest_8d35108ffe2ad173a697734a3e9938e1, _python_str_angle_hello__genexpr, _exception.getLine() );
  3339.  
  3340.         return NULL;
  3341.     }
  3342. }
  3343.  
  3344. static PyObject *MAKE_FUNCTION_genexpr_1_of_module_hello( PyObject *iterated )
  3345. {
  3346.     struct _context_genexpr_1_of_module_hello_t *_python_context = new _context_genexpr_1_of_module_hello_t;
  3347.  
  3348.     // Copy the closure values over.
  3349.    
  3350.  
  3351.     PyObject *result = Nuitka_Genexpr_New( genexpr_1_of_module_hello, _python_str_plain_hello__genexpr, iterated, 1, _python_context, _context_genexpr_1_of_module_hello_destructor );
  3352.  
  3353.     return result;
  3354. }
  3355.  
  3356.  
  3357. // The exported interface to CPython. On import of the module, this function gets called. It has have that exact function
  3358. // name.
  3359.  
  3360. static PyTracebackObject *MAKE_TRACEBACK___main__( int line )
  3361. {
  3362.    PyFrameObject *frame = MAKE_FRAME( _module___main__, _python_str_digest_8d35108ffe2ad173a697734a3e9938e1, _python_str_angle_module, line );
  3363.  
  3364.    PyTracebackObject *result = MAKE_TRACEBACK_START( frame, line );
  3365.  
  3366.    Py_DECREF( frame );
  3367.  
  3368.    assert( result );
  3369.  
  3370.    return result;
  3371. }
  3372.  
  3373. NUITKA_MODULE_INIT_FUNCTION init__main__(void)
  3374. {
  3375.     // puts( "in init__main__" );
  3376.  
  3377.  
  3378.     // Create the module object first. There are no methods initially, all are added
  3379.     // dynamically in actual code only.  Also no __doc__ is initially set, as it could not
  3380.     // contain 0 this way, added early in actual code.  No self for modules, we have no
  3381.     // use for it.
  3382.     _module___main__ = Py_InitModule4(
  3383.         "__main__",       // Module Name
  3384.         NULL,                    // No methods initially, all are added dynamically in actual code only.
  3385.         NULL,                    // No __doc__ is initially set, as it could not contain 0 this way, added early in actual code.
  3386.         NULL,                    // No self for modules, we don't use it.
  3387.         PYTHON_API_VERSION
  3388.     );
  3389.  
  3390.     assert( _module___main__ );
  3391.  
  3392.     // Initialize the constant values used.
  3393.     _initConstants();
  3394.  
  3395.     // Initialize the compiled types of Nuitka.
  3396.     PyType_Ready( &Nuitka_Function_Type );
  3397.     PyType_Ready( &Nuitka_Genexpr_Type );
  3398.  
  3399.     // Initialize the standard module attributes.
  3400.     _mvar___main_____doc__.assign0( Py_None );
  3401.     _mvar___main_____file__.assign0( _python_str_digest_8d35108ffe2ad173a697734a3e9938e1 );
  3402.  
  3403.     // Module code
  3404.     bool traceback = false;
  3405.  
  3406.     try
  3407.     {
  3408.         _current_line = 1;
  3409.         _mvar___main___math.assign( IMPORT_MODULE( _python_str_plain_math, _python_str_plain_math ) );
  3410.  
  3411.         _current_line = 3;
  3412.         _mvar___main___num_primes.assign( INCREASE_REFCOUNT( _python_int_0 ) );
  3413.         _current_line = 4;
  3414.         {
  3415.             PyObjectTemporary _python_for_loop_iterator_1( MAKE_ITERATOR( PyObjectTemporary( CALL_FUNCTION( NULL, _python_tuple_int_pos_2_int_pos_500000, PyObjectTemporary( _mvar___main___xrange.asObject() ).asObject() ) ).asObject() ) );
  3416.             while( true )
  3417.             {
  3418.                 _current_line = 4;
  3419.  
  3420.  
  3421.                 PyObject *_python_for_loop_itervalue_1 = ITERATOR_NEXT( _python_for_loop_iterator_1.asObject() );
  3422.  
  3423.                 // Check if end of iterator is reached
  3424.                 if ( _python_for_loop_itervalue_1 == NULL )
  3425.                 {
  3426.                     break;
  3427.                 }
  3428.  
  3429.                 {
  3430.                     PyObjectTemporary _python_tmp_itertemp_1( _python_for_loop_itervalue_1 );
  3431.  
  3432.                     _mvar___main___i.assign( INCREASE_REFCOUNT( _python_tmp_itertemp_1.asObject() ) );
  3433.                 }
  3434.  
  3435.                 _current_line = 5;
  3436.                 if ( CHECK_IF_TRUE( PyObjectTemporary( CALL_FUNCTION( NULL, PyObjectTemporary( MAKE_TUPLE( PyObjectTemporary( MAKE_FUNCTION_genexpr_1_of_module_hello( PyObjectTemporary( CALL_FUNCTION( NULL, PyObjectTemporary( MAKE_TUPLE( PyObjectTemporary( BINARY_OPERATION( PyNumber_Add, PyObjectTemporary( CALL_FUNCTION( NULL, PyObjectTemporary( MAKE_TUPLE( PyObjectTemporary( CALL_FUNCTION( NULL, PyObjectTemporary( MAKE_TUPLE( PyObjectTemporary( _mvar___main___i.asObject() ).asObject() ) ).asObject(), PyObjectTemporary( LOOKUP_ATTRIBUTE( PyObjectTemporary( _mvar___main___math.asObject() ).asObject(), _python_str_plain_sqrt ) ).asObject() ) ).asObject() ) ).asObject(), PyObjectTemporary( _mvar___main___int.asObject() ).asObject() ) ).asObject(), _python_int_pos_1 ) ).asObject(), _python_int_pos_2 ) ).asObject(), PyObjectTemporary( _mvar___main___xrange.asObject() ).asObject() ) ).asObject() ) ).asObject() ) ).asObject(), PyObjectTemporary( _mvar___main___all.asObject() ).asObject() ) ).asObject() ) )
  3437.                 {
  3438.                     _current_line = 6;
  3439.                     {
  3440.                         PyObjectTemporary value( _mvar___main___num_primes.asObject() );
  3441.                         PyObject *result = BINARY_OPERATION( PyNumber_InPlaceAdd, value.asObject(), _python_int_pos_1 );
  3442.  
  3443.                         if ( result != value.asObject() )
  3444.                         {
  3445.                             _mvar___main___num_primes.assign( INCREASE_REFCOUNT( result ) );
  3446.                         }
  3447.  
  3448.                         Py_DECREF( result );
  3449.                     }
  3450.                 }
  3451.  
  3452.             }
  3453.         }
  3454.         _current_line = 7;
  3455.         PRINT_ITEMS( true, NULL, PyObjectTemporary( _mvar___main___num_primes.asObject() ).asObject() );
  3456.     }
  3457.     catch ( _PythonException &_exception )
  3458.     {
  3459.         _exception.toPython();
  3460.  
  3461.         if ( traceback == false )
  3462.         {
  3463.             ADD_TRACEBACK( _module___main__, _python_str_digest_8d35108ffe2ad173a697734a3e9938e1, _python_str_angle_module, _exception.getLine() );
  3464.         }
  3465.     }
  3466. }
  3467. // The main program for C++. It needs to prepare the interpreter and then calls the
  3468. // initialization code of the __main__ module.
  3469.  
  3470. static struct _inittab _module_inittab[] =
  3471. {
  3472.  
  3473.     NULL, NULL
  3474. };
  3475.  
  3476. static bool FIND_EMBEDDED_MODULE( char const *name )
  3477. {
  3478.     struct _inittab *current = _module_inittab;
  3479.  
  3480.     while (current->name)
  3481.     {
  3482.        if ( strcmp( name, current->name ) == 0 )
  3483.        {
  3484.            current->initfunc();
  3485.  
  3486.            if ( PyErr_Occurred() )
  3487.            {
  3488.               throw _PythonException();
  3489.            }
  3490.  
  3491.            return true;
  3492.        }
  3493.  
  3494.        current++;
  3495.     }
  3496.  
  3497.     return false;
  3498. }
  3499.  
  3500. int main( int argc, char *argv[] )
  3501. {
  3502.     // Register the initialization functions for modules included in the binary if any
  3503.     int res = PyImport_ExtendInittab( _module_inittab );
  3504.     assert( res != -1 );
  3505.  
  3506.     Py_Initialize();
  3507.     PySys_SetArgv( argc, argv );
  3508.  
  3509.     init__main__();
  3510.  
  3511.     if ( PyErr_Occurred() )
  3512.     {
  3513.         PyErr_Print();
  3514.     }
  3515. }
Advertisement
Add Comment
Please, Sign In to add comment