From: Robert Bradshaw Date: Tue, 23 Sep 2008 06:45:08 +0000 (-0700) Subject: isinstance uses PyObject_TypeCheck when second argument is a type X-Git-Tag: 0.9.9.2.beta~92 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=a85eea00f700140911cebbe17d159966574008e3;p=cython.git isinstance uses PyObject_TypeCheck when second argument is a type --- diff --git a/Cython/Compiler/Builtin.py b/Cython/Compiler/Builtin.py index 3d11eeb9..d1f54162 100644 --- a/Cython/Compiler/Builtin.py +++ b/Cython/Compiler/Builtin.py @@ -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 diff --git a/Cython/Compiler/Main.py b/Cython/Compiler/Main.py index 138f5e3d..6ed7fac6 100644 --- a/Cython/Compiler/Main.py +++ b/Cython/Compiler/Main.py @@ -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), ] diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py index 9f4a46c8..64a410b9 100644 --- a/Cython/Compiler/Optimize.py +++ b/Cython/Compiler/Optimize.py @@ -140,7 +140,15 @@ class FlattenInListTransform(Visitor.VisitorTransform): 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.CythonTransform): 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 diff --git a/Cython/Compiler/Symtab.py b/Cython/Compiler/Symtab.py index 533a526f..127d7c24 100644 --- a/Cython/Compiler/Symtab.py +++ b/Cython/Compiler/Symtab.py @@ -6,8 +6,7 @@ import re 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 diff --git a/Cython/Includes/python_object.pxd b/Cython/Includes/python_object.pxd index fff3653f..57ebc7c1 100644 --- a/Cython/Includes/python_object.pxd +++ b/Cython/Includes/python_object.pxd @@ -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.