2017-03-23 | Paul Boddie | raw annotate files changeset graph | Represent integers as __attr values with bit 0 set. Since pointers must be aligned (to four-byte boundaries on many modern systems, maybe two-byte boundaries on older or embedded systems, eight-byte boundaries on some 64-bit systems), any value with bit 0 set will not be referencing an object. This avoids allocating objects for integers and instead just allows them to be passed around. Bit 0 needs to be tested when attributes are accessed, and for integers, a common instance is employed to provide any instance attributes, an instance table reference and a reference to the integer class. | integers-as-tagged-attrs |
1 import operator 2 3 class C: 4 def f(self): pass 5 6 def name(x): 7 print x.__name__ 8 print x.__parent__.__name__ 9 print str(x) 10 11 def attrname(x): 12 print x.f.__name__ 13 print x.f.__parent__.__name__ 14 print str(x.f) 15 16 c = C() 17 print c.__name__ # C 18 print c.__parent__.__name__ # __main__ 19 print str(c) # <__main__.C instance> 20 print C.__name__ # C 21 print C.__parent__.__name__ # __main__ 22 print str(C) # __main__.C 23 print c.f.__name__ # f 24 print c.f.__parent__.__name__ # C 25 print str(c.f) # __main__.C.f 26 print C.f.__name__ # f 27 print C.f.__parent__.__name__ # C 28 print str(C.f) # __main__.C.f 29 30 name(c) # C 31 # __main__ 32 # <__main__.C instance> 33 name(C) # C 34 # __main__ 35 # __main__.C 36 attrname(c) # f 37 # C 38 # __main__.C.f 39 attrname(C) # f 40 # C 41 # __main__.C.f 42 name(c.f) # f 43 # C 44 # __main__.C.f 45 name(C.f) # f 46 # C 47 # __main__.C.f 48 49 # If it were defined, operator.__name__ would be module. 50 51 print operator.__name__ # operator 52 53 # If it were defined, operator.add.__name__ would be function. 54 55 print operator.add.__name__ # add 56 print operator.add.__parent__.__name__ # operator.binary