Commit 1c9be2fc authored by Thomas Hunger's avatar Thomas Hunger

Changed the assigment code generator to emit

a direct change of a classes tp_dict instead
of SetAttr if assignment code is executed in
a class body.
To tell the code generator that we have a class
entry, entry has a new attribute "is_member".
parent 936fa570
......@@ -814,24 +814,45 @@ class NameNode(AtomicExprNode):
entry = self.entry
if entry is None:
return # There was an error earlier
# is_pyglobal seems to be True for module level-globals only.
# We use this to access class->tp_dict if necessary.
if entry.is_pyglobal:
namespace = self.entry.namespace_cname
if Options.intern_names:
code.put_error_if_neg(self.pos,
'PyObject_SetAttr(%s, %s, %s)' % (
namespace,
entry.interned_cname,
rhs.py_result()))
else:
code.put_error_if_neg(self.pos,
'PyObject_SetAttrString(%s, "%s", %s)' % (
namespace,
entry.name,
rhs.py_result()))
if debug_disposal_code:
print "NameNode.generate_assignment_code:"
print "...generating disposal code for", rhs
rhs.generate_disposal_code(code)
if entry.is_member:
# if we entry is a member we have to cheat: SetAttr does not work
# on types, so we create a descriptor which is then added to tp_dict
if Options.intern_names:
code.put_error_if_neg(self.pos,
'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
namespace,
entry.interned_cname,
rhs.py_result()))
else:
code.put_error_if_neg(self.pos,
'PyDict_SetItemString(%s->tp_dict, %s, %s)' % (
namespace,
entry.name,
rhs.py_result()))
else:
if Options.intern_names:
code.put_error_if_neg(self.pos,
'PyObject_SetAttr(%s, %s, %s)' % (
namespace,
entry.interned_cname,
rhs.py_result()))
else:
code.put_error_if_neg(self.pos,
'PyObject_SetAttrString(%s, "%s", %s)' % (
namespace,
entry.name,
rhs.py_result()))
if debug_disposal_code:
print "NameNode.generate_assignment_code:"
print "...generating disposal code for", rhs
rhs.generate_disposal_code(code)
else:
if self.type.is_pyobject:
#print "NameNode.generate_assignment_code: to", self.name ###
......
......@@ -30,6 +30,7 @@ class Entry:
# or class attribute during
# class construction
# is_special boolean Is a special class method
# is_member boolean Is an assigned class member
# is_variable boolean Is a variable
# is_cfunction boolean Is a C function
# is_cmethod boolean Is a C method of an extension type
......@@ -72,6 +73,7 @@ class Entry:
is_cglobal = 0
is_pyglobal = 0
is_special = 0
is_member = 0
is_variable = 0
is_cfunction = 0
is_cmethod = 0
......@@ -979,10 +981,7 @@ class ClassScope(Scope):
return self.outer_scope.add_string_const(value)
def lookup(self, name):
print "*** Looking for", name, "in ClassScope", self
print self.entries
res = Scope.lookup(self, name)
print "got", res, res.type
return res
......@@ -1095,7 +1094,10 @@ class CClassScope(ClassScope):
# Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef)
entry.is_pyglobal = 1
entry.is_member = 1
entry.is_pyglobal = 1 # xxx: is_pyglobal changes behaviour in so many places that
# I keep it in for now. is_member should be enough
# later on
entry.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
if Options.intern_names:
entry.interned_cname = self.intern(name)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment