PageRenderTime 38ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 0ms

/nuitka/build/include/nuitka/variables_locals.hpp

https://bitbucket.org/pombredanne/nuitka
C++ Header | 212 lines | 158 code | 35 blank | 19 comment | 22 complexity | e4807ebf52f87bcd1e940e6d8daede67 MD5 | raw file
  1. // Copyright 2013, Kay Hayen, mailto:kay.hayen@gmail.com
  2. //
  3. // Part of "Nuitka", an optimizing Python compiler that is compatible and
  4. // integrates with CPython, but also works on its own.
  5. //
  6. // Licensed under the Apache License, Version 2.0 (the "License");
  7. // you may not use this file except in compliance with the License.
  8. // You may obtain a copy of the License at
  9. //
  10. // http://www.apache.org/licenses/LICENSE-2.0
  11. //
  12. // Unless required by applicable law or agreed to in writing, software
  13. // distributed under the License is distributed on an "AS IS" BASIS,
  14. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. // See the License for the specific language governing permissions and
  16. // limitations under the License.
  17. //
  18. #ifndef __NUITKA_VARIABLES_LOCALS_H__
  19. #define __NUITKA_VARIABLES_LOCALS_H__
  20. class PyObjectLocalVariable
  21. {
  22. public:
  23. explicit PyObjectLocalVariable( PyObject *var_name, PyObject *object = NULL, bool free_value = false )
  24. {
  25. this->var_name = var_name;
  26. this->object = object;
  27. this->free_value = free_value;
  28. }
  29. explicit PyObjectLocalVariable()
  30. {
  31. this->var_name = NULL;
  32. this->object = NULL;
  33. this->free_value = false;
  34. }
  35. ~PyObjectLocalVariable()
  36. {
  37. if ( this->free_value )
  38. {
  39. Py_DECREF( this->object );
  40. }
  41. }
  42. void setVariableName( PyObject *var_name )
  43. {
  44. assertObject( var_name );
  45. assert( this->var_name == NULL);
  46. this->var_name = var_name;
  47. }
  48. void assign0( PyObject *object )
  49. {
  50. assertObject( object );
  51. if ( this->free_value )
  52. {
  53. PyObject *old_object = this->object;
  54. this->object = INCREASE_REFCOUNT( object );
  55. #ifndef NDEBUG
  56. if ( Py_REFCNT( old_object ) < 0 )
  57. {
  58. printf( "Bad at %s\n", Nuitka_String_AsString( this->var_name ) );
  59. }
  60. #endif
  61. // Free old value if any available and owned.
  62. Py_DECREF( old_object );
  63. }
  64. else
  65. {
  66. this->object = INCREASE_REFCOUNT( object );
  67. this->free_value = true;
  68. }
  69. }
  70. void assign1( PyObject *object )
  71. {
  72. assertObject( object );
  73. if ( this->free_value )
  74. {
  75. PyObject *old_object = this->object;
  76. this->object = object;
  77. #ifndef NDEBUG
  78. if ( Py_REFCNT( old_object ) < 0 )
  79. {
  80. printf( "Bad at %s\n", Nuitka_String_AsString( this->var_name ) );
  81. }
  82. #endif
  83. // Free old value if any available and owned.
  84. Py_DECREF( old_object );
  85. }
  86. else
  87. {
  88. this->object = object;
  89. this->free_value = true;
  90. }
  91. }
  92. PyObject *asObject() const
  93. {
  94. if ( this->object == NULL && this->var_name != NULL )
  95. {
  96. PyErr_Format( PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", Nuitka_String_AsString( this->var_name ) );
  97. throw PythonException();
  98. }
  99. assertObject( this->object );
  100. return this->object;
  101. }
  102. PyObject *asObject1() const
  103. {
  104. return INCREASE_REFCOUNT( this->asObject() );
  105. }
  106. bool isInitialized() const
  107. {
  108. return this->object != NULL;
  109. }
  110. void del( bool tolerant )
  111. {
  112. if ( this->object == NULL )
  113. {
  114. if ( tolerant == false )
  115. {
  116. PyErr_Format( PyExc_UnboundLocalError, "local variable '%s' referenced before assignment", Nuitka_String_AsString( this->var_name ) );
  117. throw PythonException();
  118. }
  119. }
  120. else
  121. {
  122. if ( this->free_value )
  123. {
  124. Py_DECREF( this->object );
  125. }
  126. this->object = NULL;
  127. this->free_value = false;
  128. }
  129. }
  130. PyObject *getVariableName() const
  131. {
  132. return this->var_name;
  133. }
  134. PyObject *updateLocalsDict( PyObject *locals_dict ) const
  135. {
  136. assert( PyDict_Check( locals_dict ) );
  137. if ( this->isInitialized() )
  138. {
  139. #if PYTHON_VERSION < 300
  140. int status = PyDict_SetItem(
  141. #else
  142. int status = PyObject_SetItem(
  143. #endif
  144. locals_dict,
  145. this->getVariableName(),
  146. this->asObject()
  147. );
  148. if (unlikely( status == -1 ))
  149. {
  150. throw PythonException();
  151. }
  152. }
  153. return locals_dict;
  154. }
  155. PyObject *updateLocalsDir( PyObject *locals_list ) const
  156. {
  157. assert( PyList_Check( locals_list ) );
  158. if ( this->isInitialized() )
  159. {
  160. int status = PyList_Append(
  161. locals_list,
  162. this->getVariableName()
  163. );
  164. if (unlikely( status == -1 ))
  165. {
  166. throw PythonException();
  167. }
  168. }
  169. return locals_list;
  170. }
  171. private:
  172. PyObjectLocalVariable( const PyObjectLocalVariable &other ) { assert( false ); }
  173. PyObject *var_name;
  174. PyObject *object;
  175. bool free_value;
  176. };
  177. #endif