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): ...@@ -814,24 +814,45 @@ class NameNode(AtomicExprNode):
entry = self.entry entry = self.entry
if entry is None: if entry is None:
return # There was an error earlier 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: if entry.is_pyglobal:
namespace = self.entry.namespace_cname namespace = self.entry.namespace_cname
if Options.intern_names: if entry.is_member:
code.put_error_if_neg(self.pos, # if we entry is a member we have to cheat: SetAttr does not work
'PyObject_SetAttr(%s, %s, %s)' % ( # on types, so we create a descriptor which is then added to tp_dict
namespace, if Options.intern_names:
entry.interned_cname, code.put_error_if_neg(self.pos,
rhs.py_result())) 'PyDict_SetItem(%s->tp_dict, %s, %s)' % (
else: namespace,
code.put_error_if_neg(self.pos, entry.interned_cname,
'PyObject_SetAttrString(%s, "%s", %s)' % ( rhs.py_result()))
namespace, else:
entry.name, code.put_error_if_neg(self.pos,
rhs.py_result())) 'PyDict_SetItemString(%s->tp_dict, %s, %s)' % (
if debug_disposal_code: namespace,
print "NameNode.generate_assignment_code:" entry.name,
print "...generating disposal code for", rhs rhs.py_result()))
rhs.generate_disposal_code(code)
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: else:
if self.type.is_pyobject: if self.type.is_pyobject:
#print "NameNode.generate_assignment_code: to", self.name ### #print "NameNode.generate_assignment_code: to", self.name ###
......
...@@ -30,6 +30,7 @@ class Entry: ...@@ -30,6 +30,7 @@ class Entry:
# or class attribute during # or class attribute during
# class construction # class construction
# is_special boolean Is a special class method # is_special boolean Is a special class method
# is_member boolean Is an assigned class member
# is_variable boolean Is a variable # is_variable boolean Is a variable
# is_cfunction boolean Is a C function # is_cfunction boolean Is a C function
# is_cmethod boolean Is a C method of an extension type # is_cmethod boolean Is a C method of an extension type
...@@ -72,6 +73,7 @@ class Entry: ...@@ -72,6 +73,7 @@ class Entry:
is_cglobal = 0 is_cglobal = 0
is_pyglobal = 0 is_pyglobal = 0
is_special = 0 is_special = 0
is_member = 0
is_variable = 0 is_variable = 0
is_cfunction = 0 is_cfunction = 0
is_cmethod = 0 is_cmethod = 0
...@@ -979,10 +981,7 @@ class ClassScope(Scope): ...@@ -979,10 +981,7 @@ class ClassScope(Scope):
return self.outer_scope.add_string_const(value) return self.outer_scope.add_string_const(value)
def lookup(self, name): def lookup(self, name):
print "*** Looking for", name, "in ClassScope", self
print self.entries
res = Scope.lookup(self, name) res = Scope.lookup(self, name)
print "got", res, res.type
return res return res
...@@ -1095,7 +1094,10 @@ class CClassScope(ClassScope): ...@@ -1095,7 +1094,10 @@ class CClassScope(ClassScope):
# Add an entry for a class attribute. # Add an entry for a class attribute.
entry = Scope.declare_var(self, name, type, pos, entry = Scope.declare_var(self, name, type, pos,
cname, visibility, is_cdef) 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 entry.namespace_cname = "(PyObject *)%s" % self.parent_type.typeptr_cname
if Options.intern_names: if Options.intern_names:
entry.interned_cname = self.intern(name) 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