self.type = self.type.element_ptr_type()
if self.entry.is_pyglobal or self.entry.is_builtin:
assert self.type.is_pyobject, "Python global or builtin not a Python object"
- self.is_temp = 1
+ if Options.intern_names and self.entry.is_builtin:
+ self.is_temp = 0
+ else:
+ self.is_temp = 1
if Options.intern_names:
env.use_utility_code(get_name_interned_utility_code)
else:
entry = self.entry
if entry is None:
return # There was an error earlier
- if entry.is_pyglobal or entry.is_builtin:
+ if entry.is_builtin and Options.cache_builtins:
+ return # Lookup already cached
+ elif entry.is_pyglobal or entry.is_builtin:
if entry.is_builtin:
namespace = Naming.builtins_cname
else: # entry.is_pyglobal
code.putln(
"static PyObject *%s;" % entry.pystring_cname)
+ def generate_cached_builtins_decls(self, env, code):
+ entries = env.builtin_scope().undeclared_cached_entries
+ if len(entries) > 0:
+ code.putln("")
+ for entry in entries:
+ code.putln("static PyObject *%s;" % entry.cname)
+ del entries[:]
+
class ModuleNode(Node, BlockNode):
# doc string or None
self.generate_const_definitions(env, code)
self.generate_interned_name_decls(env, code)
self.generate_py_string_decls(env, code)
+ self.generate_cached_builtins_decls(env, code)
self.body.generate_function_definitions(env, code)
self.generate_interned_name_table(env, code)
self.generate_py_string_table(env, code)
self.generate_intern_code(env, code)
#code.putln("/*--- String init code ---*/")
self.generate_string_init_code(env, code)
+ #code.putln("/*--- Builtin init code ---*/")
+ self.generate_builtin_init_code(env, code)
#code.putln("/*--- Global init code ---*/")
self.generate_global_init_code(env, code)
#code.putln("/*--- Type import code ---*/")
Naming.stringtab_cname,
code.error_goto(self.pos)))
+ def generate_builtin_init_code(self, env, code):
+ # Lookup and cache builtin objects.
+ if Options.cache_builtins:
+ for entry in env.builtin_scope().cached_entries:
+ if Options.intern_names:
+ #assert entry.interned_cname is not None
+ code.putln(
+ '%s = __Pyx_GetName(%s, %s); if (!%s) %s' % (
+ entry.cname,
+ Naming.builtins_cname,
+ entry.interned_cname,
+ entry.cname,
+ code.error_goto(entry.pos)))
+ else:
+ code.putln(
+ '%s = __Pyx_GetName(%s, "%s"); if (!%s) %s' % (
+ entry.cname,
+ Naming.builtins_cname,
+ self.entry.name,
+ entry.cname,
+ code.error_goto(entry.pos)))
+
def generate_global_init_code(self, env, code):
# Generate code to initialise global PyObject *
# variables to None.
# ----- Top-level constants used by this function
self.generate_interned_name_decls(lenv, code)
self.generate_py_string_decls(lenv, code)
+ self.generate_cached_builtins_decls(lenv, code)
#code.putln("")
#code.put_var_declarations(lenv.const_entries, static = 1)
self.generate_const_definitions(lenv, code)
def generate_execution_code(self, code):
pass
-
+
class CFuncDefNode(FuncDefNode):
# C function definition.
# Return the module-level scope containing this scope.
return self.outer_scope.global_scope()
+ def builtin_scope(self):
+ # Return the module-level scope containing this scope.
+ return self.outer_scope.builtin_scope()
+
def declare(self, name, cname, type, pos):
# Create new entry, and add to dictionary if
- # name is not None. Reports an error if already
+ # name is not None. Reports a warning if already
# declared.
dict = self.entries
if name and dict.has_key(name):
cname, type, arg_types, exception_value, exception_check = definition
function = CFuncType(type, [CFuncTypeArg("", t, None) for t in arg_types], False, exception_value, exception_check)
self.add_cfunction(name, function, None, cname, False)
-
+ self.cached_entries = []
+ self.undeclared_cached_entries = []
+
def declare_builtin(self, name, pos):
entry = self.declare(name, name, py_object_type, pos)
- entry.is_builtin = 1
+ if Options.cache_builtins:
+ entry.is_builtin = 1
+ entry.is_const = 1
+ entry.cname = Naming.builtin_prefix + name
+ self.cached_entries.append(entry)
+ self.undeclared_cached_entries.append(entry)
+ else:
+ entry.is_builtin = 1
return entry
+ def builtin_scope(self):
+ return self
+
# TODO: built in functions conflict with built in types of same name...
builtin_functions = {