Lichen

Change of translator.py

964:e98699004465
translator.py tagged-address-values
     1.1 --- a/translator.py	Sun Nov 14 00:50:17 2021 +0100
     1.2 +++ b/translator.py	Sun Nov 28 02:03:21 2021 +0100
     1.3 @@ -3,7 +3,7 @@
     1.4  """
     1.5  Translate programs.
     1.6  
     1.7 -Copyright (C) 2015, 2016, 2017, 2018 Paul Boddie <paul@boddie.org.uk>
     1.8 +Copyright (C) 2015-2018, 2021 Paul Boddie <paul@boddie.org.uk>
     1.9  
    1.10  This program is free software; you can redistribute it and/or modify it under
    1.11  the terms of the GNU General Public License as published by the Free Software
    1.12 @@ -37,7 +37,7 @@
    1.13                           AliasResult, AttrResult, Expression, InstantiationResult, \
    1.14                           InvocationResult, LogicalOperationResult, \
    1.15                           LogicalResult, NegationResult, PredefinedConstantRef, \
    1.16 -                         ReturnRef
    1.17 +                         ReturnRef, special_attributes
    1.18  from StringIO import StringIO
    1.19  import compiler
    1.20  import sys
    1.21 @@ -619,7 +619,8 @@
    1.22          del self.attrs[0]
    1.23          return AttrResult(output, refs, location,
    1.24                            context_identity, context_identity_verified,
    1.25 -                          accessor_test, accessor_stored)
    1.26 +                          accessor_test, accessor_stored, n.attrname,
    1.27 +                          self.in_assignment)
    1.28  
    1.29      def init_substitutions(self):
    1.30  
    1.31 @@ -806,9 +807,23 @@
    1.32              if ref and not ref.static():
    1.33                  parent, attrname = path.rsplit(".", 1)
    1.34  
    1.35 -                self.writestmt("__store_via_object(&%s, %s, __load_via_object(&%s, %s));" % (
    1.36 -                    encode_path(class_name), name,
    1.37 -                    encode_path(parent), attrname
    1.38 +                # NOTE: This is a superficial test for internal attributes that
    1.39 +                # NOTE: relies on such attributes being used directly and passed
    1.40 +                # NOTE: to native code.
    1.41 +
    1.42 +                if name in special_attributes:
    1.43 +                    store_op = "__store_via_object_internal"
    1.44 +                else:
    1.45 +                    store_op = "__store_via_object"
    1.46 +
    1.47 +                if attrname in special_attributes:
    1.48 +                    load_op = "__load_via_object_internal"
    1.49 +                else:
    1.50 +                    load_op = "__load_via_object"
    1.51 +
    1.52 +                self.writestmt("%s(&%s, %s, %s(&%s, %s));" % (
    1.53 +                    store_op, encode_path(class_name), name,
    1.54 +                    load_op, encode_path(parent), attrname
    1.55                      ))
    1.56  
    1.57      def process_from_node(self, n):
    1.58 @@ -883,6 +898,11 @@
    1.59                      compiler.ast.AssAttr(compiler.ast.Name("self"), name, "OP_ASSIGN"),
    1.60                      compiler.ast.Name(name))
    1.61  
    1.62 +        # Record the value stack level.
    1.63 +
    1.64 +        self.writestmt("__section *__stack_section = __stack.stackdesc->current;")
    1.65 +        self.writestmt("char *__stack_level = __stack_section->level; (void) __stack_level;")
    1.66 +
    1.67          # Produce the body and any additional return statement.
    1.68  
    1.69          expr = self.process_structure_node(n.code) or \
    1.70 @@ -1281,8 +1301,8 @@
    1.71              self.record_temp("__tmp_values")
    1.72  
    1.73          # Arguments are presented in a temporary frame array with any context
    1.74 -        # always being the first argument. Where it would be unused, it may be
    1.75 -        # set to null.
    1.76 +        # always being the first argument. Where the context would be unused, it
    1.77 +        # may be set to null.
    1.78  
    1.79          if context_required:
    1.80              if have_access_context:
    1.81 @@ -1292,6 +1312,8 @@
    1.82          else:
    1.83              context_arg = "__NULL"
    1.84  
    1.85 +        # Introduce any context.
    1.86 +
    1.87          args = [context_arg]
    1.88          reserved_args = 1
    1.89  
    1.90 @@ -1324,12 +1346,9 @@
    1.91          for i, arg in enumerate(n.args):
    1.92              argexpr = self.process_structure_node(arg)
    1.93  
    1.94 -            # Obtain an appropriate argument representation. This prevents
    1.95 -            # copyable values from being mutable, but care must be taken to
    1.96 -            # prevent special internal attribute values represented using
    1.97 -            # attributes from being modified.
    1.98 -
    1.99 -            argrepr = argexpr.as_arg()
   1.100 +            # Obtain an appropriate argument representation.
   1.101 +
   1.102 +            argrepr = str(argexpr)
   1.103  
   1.104              # Store a keyword argument, either in the argument list or
   1.105              # in a separate keyword argument list for subsequent lookup.
   1.106 @@ -1758,7 +1777,7 @@
   1.107          if self.in_try_finally or self.in_try_except:
   1.108              self.writestmt("__Return(%s);" % expr)
   1.109          else:
   1.110 -            self.writestmt("return %s;" % expr)
   1.111 +            self.writestmt("return __return(%s, __stack_section, __stack_level);" % expr)
   1.112  
   1.113          return ReturnRef()
   1.114  
   1.115 @@ -2131,11 +2150,13 @@
   1.116  
   1.117          if names:
   1.118              names.sort()
   1.119 -            self.writeline("__attr %s;" % ", ".join(names))
   1.120 +            for n in names:
   1.121 +                self.writeline("__attr %s = (__attr) {.rawvalue = 0};" % n)
   1.122  
   1.123          if volatile_names:
   1.124              volatile_names.sort()
   1.125 -            self.writeline("volatile __attr %s;" % ", ".join(volatile_names))
   1.126 +            for n in volatile_names:
   1.127 +                self.writeline("volatile __attr %s = (__attr) {.rawvalue = 0};" % n)
   1.128  
   1.129          self.flush_unit(name, out)
   1.130