self.in_try_finally = 0
self.exc_vars = None
- self.temps_allocated = [] # of (name, type, manage_ref)
+ self.temps_allocated = [] # of (name, type, manage_ref, static)
self.temps_free = {} # (type, manage_ref) -> list of free vars with same type/managed status
self.temps_used_type = {} # name -> (type, manage_ref)
self.temp_counter = 0
# temp handling
- def allocate_temp(self, type, manage_ref):
+ def allocate_temp(self, type, manage_ref, static=False):
"""
Allocates a temporary (which may create a new one or get a previously
allocated and released one of the same type). Type is simply registered
still has to be passed. It is recommended to pass False by convention
if it is known that type will never be a Python object.
+ static=True marks the temporary declaration with "static".
+ This is only used when allocating backing store for a module-level
+ C array literals.
+
A C string referring to the variable is returned.
"""
if type.is_const:
self.temp_counter += 1
result = "%s%d" % (Naming.codewriter_temp_prefix, self.temp_counter)
if not result in self.names_taken: break
- self.temps_allocated.append((result, type, manage_ref))
+ self.temps_allocated.append((result, type, manage_ref, static))
self.temps_used_type[result] = (type, manage_ref)
if DebugFlags.debug_temp_code_comments:
self.owner.putln("/* %s allocated */" % result)
that are currently in use.
"""
used = []
- for name, type, manage_ref in self.temps_allocated:
+ for name, type, manage_ref, static in self.temps_allocated:
freelist = self.temps_free.get((type, manage_ref))
if freelist is None or name not in freelist:
used.append((name, type, manage_ref and type.is_pyobject))
"""Return a list of (cname, type) tuples of refcount-managed Python objects.
"""
return [(cname, type)
- for cname, type, manage_ref in self.temps_allocated
+ for cname, type, manage_ref, static in self.temps_allocated
if manage_ref]
def all_free_managed_temps(self):
self.putln(";")
def put_temp_declarations(self, func_context):
- for name, type, manage_ref in func_context.temps_allocated:
+ for name, type, manage_ref, static in func_context.temps_allocated:
decl = type.declaration_code(name)
if type.is_pyobject:
self.putln("%s = NULL;" % decl)
import MemoryView
self.putln("%s = %s;" % (decl, MemoryView.memslice_entry_init))
else:
- self.putln("%s;" % decl)
+ self.putln("%s%s;" % (static and "static " or "", decl))
def put_h_guard(self, guard):
self.putln("#ifndef %s" % guard)
return # There was an error earlier
if (self.entry.type.is_ptr and isinstance(rhs, ListNode)
- and not self.lhs_of_first_assignment):
+ and not self.lhs_of_first_assignment and not rhs.in_module_scope):
error(self.pos, "Literal list must be assigned to pointer at time of declaration")
# is_pyglobal seems to be True for module level-globals only.
obj_conversion_errors = []
type = list_type
+ in_module_scope = False
gil_message = "Constructing Python list"
node = SequenceNode.analyse_types(self, env)
node.obj_conversion_errors = held_errors()
release_errors(ignore=True)
+ if env.is_module_scope:
+ self.in_module_scope = True
return node
def coerce_to(self, dst_type, env):
t.constant_result = tuple(self.constant_result)
return t
+ def allocate_temp_result(self, code):
+ if self.type.is_array and self.in_module_scope:
+ self.temp_code = code.funcstate.allocate_temp(
+ self.type, manage_ref=False, static=True)
+ else:
+ SequenceNode.allocate_temp_result(self, code)
+
def release_temp_result(self, env):
if self.type.is_array:
# To be valid C++, we must allocate the memory on the stack
print_struct(aa[0])
print_struct([1, 2, <double**>1])
+cdef int m_int = -1
+cdef int* m_iarray = [4, m_int]
+cdef int** m_piarray = [m_iarray, &m_int]
+cdef char** m_carray = [b"a", b"bc"]
+cdef MyStruct* m_structarray = [[m_int,0,NULL], [1,m_int+1,NULL]]
+
+def test_module_level():
+ """
+ >>> test_module_level()
+ 4 -1
+ 4 -1
+ True True
+ 1 0 True
+ """
+ print m_iarray[0], m_iarray[1]
+ print m_piarray[0][0], m_piarray[1][0]
+ print m_carray[0] == b"a", m_carray[1] == b"bc"
+ print_struct(m_structarray[1])
+
+
# Make sure it's still naturally an object.
[0,1,2,3].append(4)