Skip to content

member functions and memory #133

@alexjbest

Description

@alexjbest

Currently we see the following error in Sage

sage: R.<y> = QQ[]
sage: K = NumberField(y^2-y-1,'a')
sage: A = pari(K).alginit([2,[[],[]],[0,0]])
sage: K(A.algb())
1
sage: K(A.algb())
---------------------------------------------------------------------------
SystemError                               Traceback (most recent call last)
Input In [20], in <cell line: 5>()
      3 A = pari(K).alginit([Integer(2),[[],[]],[Integer(0),Integer(0)]])
      4 K(A.algb())
----> 5 K(A.algb())

File cypari2/auto_gen.pxi:718, in cypari2.gen.Gen_base.algb()

File cypari2/stack.pyx:182, in cypari2.stack.new_gen()

File cypari2/stack.pyx:212, in cypari2.stack.new_gen_noclear()

SystemError: new_gen() argument not on PARI stack, not on PARI heap and not a universal constant

We hypothesised that this is because the member functions are treated differently by pari and gp, in pari.desc the prototype is marked with m to tell gp to copy the return value to the stack. Aurel explained this to me a bit after talking with Bill and I wrote the following patch based on my understanding of the situation but running ./tests/rundoctest.py gives memory leaks, so I guess it's not quite correct, expert advice would be great!

diff --git a/autogen/ret.py b/autogen/ret.py
index 2186297..a004430 100644
--- a/autogen/ret.py
+++ b/autogen/ret.py
@@ -54,6 +54,13 @@ class PariReturnGEN(PariReturn):
         s = "        return new_gen({name})\n"
         return s.format(name=self.name)
 
+class PariReturnmGEN(PariReturn):
+    def ctype(self):
+        return "GEN"
+    def return_code(self):
+        s = "        return copy_gen({name})\n"
+        return s.format(name=self.name)
+
 class PariReturnInt(PariReturn):
     def ctype(self):
         return "int"
@@ -78,7 +85,7 @@ class PariReturnVoid(PariReturn):
 
 pari_ret_types = {
         '':  PariReturnGEN,
-        'm': PariReturnGEN,
+        'm': PariReturnmGEN,
         'i': PariReturnInt,
         'l': PariReturnLong,
         'u': PariReturnULong,
diff --git a/cypari2/gen.pyx b/cypari2/gen.pyx
index 247b1ad..d371931 100644
--- a/cypari2/gen.pyx
+++ b/cypari2/gen.pyx
@@ -72,7 +72,7 @@ from .convert cimport PyObject_AsGEN, gen_to_integer
 from .pari_instance cimport (prec_bits_to_words, prec_words_to_bits,
                              default_bitprec, get_var)
 from .stack cimport (new_gen, new_gens2, new_gen_noclear,
-                     clone_gen, clear_stack, reset_avma,
+                     clone_gen, copy_gen, clear_stack, reset_avma,
                      remove_from_pari_stack, move_gens_to_heap)
 from .closure cimport objtoclosure
 
diff --git a/cypari2/pari_instance.pyx b/cypari2/pari_instance.pyx
index 1366ab4..494bb11 100644
--- a/cypari2/pari_instance.pyx
+++ b/cypari2/pari_instance.pyx
@@ -287,7 +287,7 @@ from .string_utils cimport to_string, to_bytes
 from .paridecl cimport *
 from .paripriv cimport *
 from .gen cimport Gen, objtogen
-from .stack cimport (new_gen, new_gen_noclear, clear_stack,
+from .stack cimport (new_gen, new_gen_noclear, clear_stack, clone_gen, copy_gen,
                      set_pari_stack_size, before_resize, after_resize)
 from .handle_error cimport _pari_init_error_handling
 from .closure cimport _pari_init_closure
diff --git a/cypari2/stack.pxd b/cypari2/stack.pxd
index 00ef3a0..40388fb 100644
--- a/cypari2/stack.pxd
+++ b/cypari2/stack.pxd
@@ -5,6 +5,7 @@ from .gen cimport Gen_base, Gen
 cdef Gen new_gen(GEN x)
 cdef new_gens2(GEN x, GEN y)
 cdef Gen new_gen_noclear(GEN x)
+cdef Gen copy_gen(GEN x)
 cdef Gen clone_gen(GEN x)
 cdef Gen clone_gen_noclear(GEN x)
 
diff --git a/cypari2/stack.pyx b/cypari2/stack.pyx
index 95a7f1b..1370d95 100644
--- a/cypari2/stack.pyx
+++ b/cypari2/stack.pyx
@@ -224,6 +224,12 @@ cdef Gen new_gen_noclear(GEN x):
     return z
 
 
+cdef Gen copy_gen(GEN x):
+    t = Gen_stack_new(x)
+    #remove_from_pari_stack(y)
+    clear_stack()
+    return t
+
 cdef Gen clone_gen(GEN x):
     x = gclone(x)
     clear_stack()

Original issue from code Aurel Page and Eloi Torrents were writing at CIRM

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions