--- a/Cython/Compiler/Builtin.py Mon Sep 22 22:08:56 2008 -0700
+++ b/Cython/Compiler/Builtin.py Mon Sep 22 23:45:08 2008 -0700
@@ -181,7 +181,8 @@ def init_builtins():
init_builtin_funcs()
init_builtin_types()
init_builtin_structs()
- global list_type, tuple_type, dict_type, unicode_type
+ global list_type, tuple_type, dict_type, unicode_type, type_type
+ type_type = builtin_scope.lookup('type').type
list_type = builtin_scope.lookup('list').type
tuple_type = builtin_scope.lookup('tuple').type
dict_type = builtin_scope.lookup('dict').type
--- a/Cython/Compiler/Main.py Mon Sep 22 22:08:56 2008 -0700
+++ b/Cython/Compiler/Main.py Mon Sep 22 23:45:08 2008 -0700
@@ -81,7 +81,7 @@ class Context:
from ParseTreeTransforms import CreateClosureClasses, MarkClosureVisitor, DecoratorTransform
from ParseTreeTransforms import InterpretCompilerDirectives
from AutoDocTransforms import EmbedSignature
- from Optimize import FlattenInListTransform, SwitchTransform, OptimizeRefcounting
+ from Optimize import FlattenInListTransform, SwitchTransform, FinalOptimizePhase
from Buffer import IntroduceBufferAuxiliaryVars
from ModuleNode import check_c_classes
@@ -106,7 +106,7 @@ class Context:
_check_c_classes,
AnalyseExpressionsTransform(self),
SwitchTransform(),
- OptimizeRefcounting(self),
+ FinalOptimizePhase(self),
# SpecialFunctions(self),
# CreateClosureClasses(context),
]
--- a/Cython/Compiler/Optimize.py Mon Sep 22 22:08:56 2008 -0700
+++ b/Cython/Compiler/Optimize.py Mon Sep 22 23:45:08 2008 -0700
@@ -140,7 +140,15 @@ class FlattenInListTransform(Visitor.Vis
return node
-class OptimizeRefcounting(Visitor.CythonTransform):
+class FinalOptimizePhase(Visitor.CythonTransform):
+ """
+ This visitor handles several commuting optimizations, and is run
+ just before the C code generation phase.
+
+ The optimizations currently implemented in this class are:
+ - Eliminate None assignment and refcounting for first assignment.
+ - isinstance -> typecheck for cdef types
+ """
def visit_SingleAssignmentNode(self, node):
if node.first:
lhs = node.lhs
@@ -152,3 +160,22 @@ class OptimizeRefcounting(Visitor.Cython
lhs.skip_assignment_decref = True
return node
+ def visit_SimpleCallNode(self, node):
+ self.visitchildren(node)
+ if node.function.type.is_cfunction:
+ if node.function.name == 'isinstance':
+ type_arg = node.args[1]
+ if type_arg.type.is_builtin_type and type_arg.type.name == 'type':
+ object_module = self.context.find_module('python_object')
+ node.function.entry = object_module.lookup('PyObject_TypeCheck')
+ node.function.type = node.function.entry.type
+ PyTypeObjectPtr = PyrexTypes.CPtrType(object_module.lookup('PyTypeObject').type)
+ node.args[1] = ExprNodes.CastNode(node.args[1], PyTypeObjectPtr)
+ # Remove when result_code stuff is put in its proper place...
+ node.function.result_code = node.function.entry.cname
+ node.args[1].result_code = node.args[1].arg.result_as(PyTypeObjectPtr)
+ if node.is_temp:
+ node.allocate_temp(None, node.result_code)
+ else:
+ node.allocate_temp(None)
+ return node
--- a/Cython/Compiler/Symtab.py Mon Sep 22 22:08:56 2008 -0700
+++ b/Cython/Compiler/Symtab.py Mon Sep 22 23:45:08 2008 -0700
@@ -6,8 +6,7 @@ from Cython import Utils
from Cython import Utils
from Errors import warning, error, InternalError
from StringEncoding import EncodedString
-import Options
-import Naming
+import Options, Naming
import PyrexTypes
from PyrexTypes import py_object_type
import TypeSlots
@@ -711,7 +710,7 @@ class BuiltinScope(Scope):
entry = self.declare_type(name, type, None, visibility='extern')
var_entry = Entry(name = entry.name,
- type = py_object_type,
+ type = self.lookup('type').type, # make sure "type" is the first type declared...
pos = entry.pos,
cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
var_entry.is_variable = 1
@@ -1110,8 +1109,9 @@ class ModuleScope(Scope):
# variable entry attached to it. For the variable entry,
# we use a read-only C global variable whose name is an
# expression that refers to the type object.
+ import Builtin
var_entry = Entry(name = entry.name,
- type = py_object_type,
+ type = Builtin.type_type,
pos = entry.pos,
cname = "((PyObject*)%s)" % entry.type.typeptr_cname)
var_entry.is_variable = 1
--- a/Cython/Includes/python_object.pxd Mon Sep 22 22:08:56 2008 -0700
+++ b/Cython/Includes/python_object.pxd Mon Sep 22 23:45:08 2008 -0700
@@ -233,7 +233,7 @@ cdef extern from "Python.h":
# pointer of type PyTypeObject*, except when the incremented
# reference count is needed.
- bint PyObject_TypeCheck(object o, object type) # object o, PyTypeObject *type)
+ bint PyObject_TypeCheck(object o, PyTypeObject *type)
# Return true if the object o is of type type or a subtype of
# type. Both parameters must be non-NULL.