Pārlūkot izejas kodu

Fix a number of JIT-related issues, implement 'assign' in JIT

jonathanvdc 8 gadi atpakaļ
vecāks
revīzija
30be6a2408
2 mainītis faili ar 45 papildinājumiem un 6 dzēšanām
  1. 43 4
      kernel/modelverse_jit/jit.py
  2. 2 2
      kernel/modelverse_jit/tree_ir.py

+ 43 - 4
kernel/modelverse_jit/jit.py

@@ -340,7 +340,7 @@ class AnalysisState(object):
                 tree_ir.ReadDictionaryValueInstruction(
                     user_root.create_load(),
                     tree_ir.LiteralInstruction('globals')),
-                var_id.create_load()))
+                var_name.create_load()))
 
         err_block = tree_ir.SelectInstruction(
             tree_ir.BinaryInstruction(
@@ -390,7 +390,7 @@ class AnalysisState(object):
                     tree_ir.CreateNodeInstruction())))
 
     def analyze_global(self, instruction_id):
-        """Tries to analyze the given 'global' (declaration) function."""
+        """Tries to analyze the given 'global' (declaration) instruction."""
         var_id, = yield [("RD", [instruction_id, "var"])]
 
         # To resolve a variable, we'll do something along the
@@ -445,8 +445,46 @@ class AnalysisState(object):
                                 var_name.create_load(),
                                 global_var.create_load())),
                         tree_ir.EmptyInstruction())),
-                global_var.create_load())
-        )
+                global_var.create_load()))
+
+    def analyze_assign(self, instruction_id):
+        """Tries to analyze the given 'assign' instruction."""
+        var_id, value_id = yield [("RD", [instruction_id, "var"]),
+                                  ("RD", [instruction_id, "value"])]
+
+        try:
+            gen = self.analyze_all([var_id, value_id])
+            inp = None
+            while True:
+                inp = yield gen.send(inp)
+        except primitive_functions.PrimitiveFinished as ex:
+            var_r, value_r = ex.result
+
+        # Assignments work like this:
+        #
+        #     value_link = yield [("RDE", [variable, "value"])]
+        #     _, _ =       yield [("CD", [variable, "value", value]),
+        #                         ("DE", [value_link])]
+
+        variable = tree_ir.StoreLocalInstruction('variable', var_r)
+        value = tree_ir.StoreLocalInstruction('value', value_r)
+        value_link = tree_ir.StoreLocalInstruction(
+            'value_link',
+            tree_ir.ReadDictionaryEdgeInstruction(
+                variable.create_load(),
+                tree_ir.LiteralInstruction('value')))
+
+        raise primitive_functions.PrimitiveFinished(
+            tree_ir.create_block(
+                variable,
+                value,
+                value_link,
+                tree_ir.CreateDictionaryEdgeInstruction(
+                    variable.create_load(),
+                    tree_ir.LiteralInstruction('value'),
+                    value.create_load()),
+                tree_ir.DeleteEdgeInstruction(
+                    value_link.create_load())))
 
     instruction_analyzers = {
         'if' : analyze_if,
@@ -456,6 +494,7 @@ class AnalysisState(object):
         'resolve' : analyze_resolve,
         'declare' : analyze_declare,
         'global' : analyze_global,
+        'assign' : analyze_assign,
         'output' : analyze_output
     }
 

+ 2 - 2
kernel/modelverse_jit/tree_ir.py

@@ -256,7 +256,7 @@ class CallInstruction(Instruction):
             '%s = %s(%s) ' % (
                 code_generator.get_result_name(self),
                 self.target.generate_python_use(code_generator),
-                [arg.generate_python_use(code_generator) for arg in self.argument_list]))
+                ', '.join([arg.generate_python_use(code_generator) for arg in self.argument_list])))
 
 class BinaryInstruction(Instruction):
     """An instruction that performs a binary operation."""
@@ -470,7 +470,7 @@ class LocalExistsInstruction(LocalInstruction):
     def generate_python_use(self, code_generator):
         """Generates a Python expression that retrieves this instruction's
            result. The expression is returned as a string."""
-        return '%s in locals()' % self.name
+        return "'%s' in locals()" % self.name
 
 class LoadIndexInstruction(Instruction):
     """An instruction that produces a value by indexing a specified expression with