1.1 --- a/transresults.py Sun Nov 14 00:50:17 2021 +0100
1.2 +++ b/transresults.py Sun Nov 28 02:03:21 2021 +0100
1.3 @@ -24,6 +24,8 @@
1.4 from results import ConstantValueRef, InstanceRef, LiteralSequenceRef, NameRef, \
1.5 ResolvedNameRef, Result
1.6
1.7 +special_attributes = ("__args__", "__data__", "__key__", "__size__")
1.8 +
1.9 # Classes representing intermediate translation results.
1.10
1.11 class ReturnRef:
1.12 @@ -59,12 +61,6 @@
1.13 def __repr__(self):
1.14 return "Expression(%r)" % self.s
1.15
1.16 - def as_arg(self):
1.17 -
1.18 - "Return the expression without any mutable tag."
1.19 -
1.20 - return self.s
1.21 -
1.22 class TrResolvedNameRef(ResolvedNameRef):
1.23
1.24 "A reference to a name in the translation."
1.25 @@ -114,54 +110,58 @@
1.26 # Qualified names must be converted into parent-relative assignments.
1.27
1.28 elif self.parent:
1.29 - return "__store_via_object(&%s, %s, %s)" % (
1.30 - encode_path(self.parent), self.attrname, self.expr)
1.31 +
1.32 + # NOTE: This is a superficial test for internal attributes that
1.33 + # NOTE: relies on such attributes being used directly and passed
1.34 + # NOTE: to native code.
1.35 +
1.36 + if self.attrname in special_attributes:
1.37 + op = "__store_via_object_internal"
1.38 + else:
1.39 + op = "__store_via_object"
1.40 +
1.41 + return "%s(&%s, %s, %s)" % (
1.42 + op, encode_path(self.parent), self.attrname, self.expr)
1.43
1.44 # All other assignments involve the names as they were given.
1.45
1.46 else:
1.47 - return "%s = %s" % (self.attrname, self.expr)
1.48 + return "%s = __store_local(%s, %s)" % (self.attrname, self.attrname, self.expr)
1.49
1.50 # Expressions.
1.51
1.52 - elif self.static_name:
1.53 - return "__ATTRVALUE(&%s)" % self.static_name
1.54 + if self.static_name:
1.55 + s = "__ATTRVALUE(&%s)" % self.static_name
1.56
1.57 # Qualified names must be converted into parent-relative accesses.
1.58
1.59 elif self.parent:
1.60 - return "__load_via_object(&%s, %s)" % (
1.61 - encode_path(self.parent), self.attrname)
1.62 +
1.63 + # NOTE: This is a superficial test for internal attributes that
1.64 + # NOTE: relies on such attributes being used directly and passed
1.65 + # NOTE: to native code.
1.66 +
1.67 + if self.attrname in special_attributes:
1.68 + op = "__load_via_object_internal"
1.69 + else:
1.70 + op = "__load_via_object"
1.71 +
1.72 + s = "%s(&%s, %s)" % (
1.73 + op, encode_path(self.parent), self.attrname)
1.74
1.75 # All other accesses involve the names as they were given.
1.76
1.77 else:
1.78 - return "(%s)" % self.attrname
1.79 -
1.80 - def as_arg(self):
1.81 -
1.82 - "Return the expression without any mutable tag."
1.83 -
1.84 - s = self.__str__()
1.85 + s = "(%s)" % self.attrname
1.86
1.87 - # NOTE: This is a superficial test for internal attributes that relies
1.88 - # NOTE: on such attributes being used directly and passed to native
1.89 - # NOTE: code.
1.90 -
1.91 - if self.attrname in ("__data__", "__size__"):
1.92 - return s
1.93 - else:
1.94 - return "__TO_IMMUTABLE(%s)" % s
1.95 + return "__load(%s)" % s
1.96
1.97 class TrConstantValueRef(ConstantValueRef):
1.98
1.99 "A constant value reference in the translation."
1.100
1.101 def __str__(self):
1.102 - return encode_literal_constant(self.number)
1.103 -
1.104 - def as_arg(self):
1.105 - return self.__str__()
1.106 + return "__load(%s)" % encode_literal_constant(self.number)
1.107
1.108 class TrLiteralSequenceRef(LiteralSequenceRef):
1.109
1.110 @@ -170,9 +170,6 @@
1.111 def __str__(self):
1.112 return str(self.node)
1.113
1.114 - def as_arg(self):
1.115 - return self.__str__()
1.116 -
1.117 class TrInstanceRef(InstanceRef):
1.118
1.119 "A reference representing instantiation of a class."
1.120 @@ -193,15 +190,13 @@
1.121 def __repr__(self):
1.122 return "TrResolvedInstanceRef(%r, %r)" % (self.ref, self.expr)
1.123
1.124 - def as_arg(self):
1.125 - return self.__str__()
1.126 -
1.127 class AttrResult(Result, InstructionSequence):
1.128
1.129 "A translation result for an attribute access."
1.130
1.131 def __init__(self, instructions, refs, location, context_identity,
1.132 - context_identity_verified, accessor_test, accessor_stored):
1.133 + context_identity_verified, accessor_test, accessor_stored,
1.134 + attrname, assignment):
1.135
1.136 InstructionSequence.__init__(self, instructions)
1.137 self.refs = refs
1.138 @@ -210,6 +205,8 @@
1.139 self.context_identity_verified = context_identity_verified
1.140 self.accessor_test = accessor_test
1.141 self.accessor_stored = accessor_stored
1.142 + self.attrname = attrname
1.143 + self.assignment = assignment
1.144
1.145 def references(self):
1.146 return self.refs
1.147 @@ -244,16 +241,23 @@
1.148 return bool(self.instructions)
1.149
1.150 def __str__(self):
1.151 - return encode_instructions(self.instructions)
1.152 + s = encode_instructions(self.instructions)
1.153 +
1.154 + # NOTE: This includes a superficial test for internal attributes that
1.155 + # NOTE: relies on such attributes being used directly and passedto
1.156 + # NOTE: native code.
1.157 +
1.158 + if self.assignment or self.accessor_test or self.attrname in special_attributes:
1.159 + return s
1.160 + else:
1.161 + return "__load(%s)" % s
1.162
1.163 def __repr__(self):
1.164 - return "AttrResult(%r, %r, %r, %r, %r, %r, %r)" % (
1.165 + return "AttrResult(%r, %r, %r, %r, %r, %r, %r, %r, %r)" % (
1.166 self.instructions, self.refs, self.location,
1.167 self.context_identity, self.context_identity_verified,
1.168 - self.accessor_test, self.accessor_stored)
1.169 -
1.170 - def as_arg(self):
1.171 - return self.__str__()
1.172 + self.accessor_test, self.accessor_stored, self.attrname,
1.173 + self.assignment)
1.174
1.175 class AliasResult(NameRef, Result):
1.176
1.177 @@ -308,9 +312,6 @@
1.178 def __repr__(self):
1.179 return "AliasResult(%r, %r)" % (self.name_ref, self.refs)
1.180
1.181 - def as_arg(self):
1.182 - return self.__str__()
1.183 -
1.184 class InvocationResult(Result, InstructionSequence):
1.185
1.186 "A translation result for an invocation."
1.187 @@ -321,9 +322,6 @@
1.188 def __repr__(self):
1.189 return "InvocationResult(%r)" % self.instructions
1.190
1.191 - def as_arg(self):
1.192 - return self.__str__()
1.193 -
1.194 class InstantiationResult(InvocationResult, TrInstanceRef):
1.195
1.196 "An instantiation result acting like an invocation result."
1.197 @@ -364,9 +362,6 @@
1.198 def __repr__(self):
1.199 return "PredefinedConstantRef(%r)" % self.value
1.200
1.201 - def as_arg(self):
1.202 - return self.__str__()
1.203 -
1.204 class LogicalResult(Result):
1.205
1.206 "A logical expression result."
1.207 @@ -412,9 +407,6 @@
1.208 def __repr__(self):
1.209 return "NegationResult(%r)" % self.expr
1.210
1.211 - def as_arg(self):
1.212 - return self.__str__()
1.213 -
1.214 class LogicalOperationResult(LogicalResult):
1.215
1.216 "A logical operation result."
1.217 @@ -487,7 +479,4 @@
1.218 def __repr__(self):
1.219 return "LogicalOperationResult(%r, %r)" % (self.exprs, self.conjunction)
1.220
1.221 - def as_arg(self):
1.222 - return self.__str__()
1.223 -
1.224 # vim: tabstop=4 expandtab shiftwidth=4