1. 17 Jan, 2015 1 commit
  2. 29 Dec, 2014 3 commits
    • Matthew Johnson's avatar
      Add __hash__() and __eq__() to MemoryViewSliceType to avoid distinct · 5e77573c
      Matthew Johnson authored
      object id hashes resulting in duplicate utility code in specialization
      
      The CppClassType.specialize() method uses a hash table to avoid
      re-generating specializations and thus, for example, re-generating utility code:
      
          # values is a dict where values are instances of classes in
          # PyrexTypes.py
          key = tuple(values.items())
          if key in self.specializations:
              return self.specializations[key]
          # instantiate new CppClassType, eventually resulting in utility code
      
      However, because MemoryViewSliceType used the default (object-id) hash,
      distinct MemoryViewSliceType instances would ultimately give rise to
      distinct keys. As a result, code like
      
           def test_memviews_same(a,b):
               cdef vector[double[:]] aa = a
               cdef vector[double[:]] bb = b
      
      would successfully pass through the Cython compiler but then result in a
      C++ compiler error due to redefinition of utility code:
      
          error: redefinition of 'std::vector<__Pyx_memviewslice> __pyx_convert_vector_from_py___Pyx_memviewslice(PyObject*)'
      
      To allow the hash table in CppClassType.specialize() to identify 'equal'
      specializations of CppClassType, we can add __hash__() and __eq__()
      methods based on the existing
      MemoryViewSliceType.same_as_resolved_type() method. Other classes in
      PyrexTypes.py also have __hash__() methods defined and the choices made
      here appear roughly consistent.
      
      This addition allows the above example to compile successfully.
      5e77573c
    • Matthew Johnson's avatar
      Add MemoryViewSliceType.specialization_name() to include dtype in name · 6460e490
      Matthew Johnson authored
      Calling inherited BaseType.specialization_name() on a
      MemoryViewSliceType generates a name like "Pyx_memviewslice", which
      meant, for example, that generated utility code could have a name like
      
          __pyx_convert_from_py__Pyx_memviewslice
      
      which would collide with utility code generated for other memoryviews
      that might have other base types. That would mean something like
      
          def test_memviews_diff(a,b):
              cdef vector[double[:]] aa = a
              cdef vector[int[:]] bb = b
      
      would first have a compile error (function redefinition due to how
      utility code is currently generated) and second, if only one such
      utility function were emitted instead of one for each memoryview base
      type, have problems with any type-specific generated code, e.g.
      
          // generated inside __Pyx_PyObject_to_MemoryviewSlice,
          // which is called from __pyx_convert_vector_from_py___Pyx_memviewslice
          // note __Pyx_TypeInfo_double
          retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, 0,
                                                       PyBUF_RECORDS, 1,
                                                       &__Pyx_TypeInfo_double, stack,
                                                       &result, obj);
      
      By adding the dtype tag to the name string returned by
      specialization_name(), distinct utility code functions are generated (at
      least in the case above) and thus there is no name collision.
      6460e490
    • Stefan Behnel's avatar
      db4001fa
  3. 28 Dec, 2014 6 commits
  4. 27 Dec, 2014 11 commits
  5. 26 Dec, 2014 6 commits
  6. 25 Dec, 2014 3 commits
  7. 24 Dec, 2014 1 commit
  8. 23 Dec, 2014 2 commits
  9. 19 Dec, 2014 5 commits
  10. 18 Dec, 2014 1 commit
  11. 17 Dec, 2014 1 commit