Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r88822:806213151c0a
Date: 2016-12-02 16:20 +0100
http://bitbucket.org/pypy/pypy/changeset/806213151c0a/

Log:    implement LOAD_CLASSDEREF

diff --git a/pypy/interpreter/astcompiler/assemble.py 
b/pypy/interpreter/astcompiler/assemble.py
--- a/pypy/interpreter/astcompiler/assemble.py
+++ b/pypy/interpreter/astcompiler/assemble.py
@@ -682,12 +682,11 @@
     ops.JUMP_IF_FALSE_OR_POP: 0,
     ops.POP_JUMP_IF_TRUE: -1,
     ops.POP_JUMP_IF_FALSE: -1,
-    # TODO
     ops.JUMP_IF_NOT_DEBUG: 0,
 
     # TODO
     ops.BUILD_LIST_FROM_ARG: 1,
-    # TODO
+
     ops.LOAD_CLASSDEREF: 1,
 }
 
diff --git a/pypy/interpreter/astcompiler/codegen.py 
b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -243,6 +243,8 @@
                 op = name_ops_fast(ctx)
         elif scope == symtable.SCOPE_FREE:
             op = name_ops_deref(ctx)
+            if op == ops.LOAD_DEREF and isinstance(self, ClassCodeGenerator):
+                op = ops.LOAD_CLASSDEREF
             container = self.free_vars
         elif scope == symtable.SCOPE_CELL:
             op = name_ops_deref(ctx)
diff --git a/pypy/interpreter/astcompiler/test/test_compiler.py 
b/pypy/interpreter/astcompiler/test/test_compiler.py
--- a/pypy/interpreter/astcompiler/test/test_compiler.py
+++ b/pypy/interpreter/astcompiler/test/test_compiler.py
@@ -1151,6 +1151,17 @@
         assert e.value.msg == (
             "'await' expressions in comprehensions are not supported")
 
+    def test_load_classderef(self):
+        source = """if 1:
+        def f():
+            x = 42
+            class X:
+                locals()["x"] = 43
+                y = x
+            return X.y
+        """
+        yield self.st, source, "f()", 43
+
 
 class AppTestCompiler:
 
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -348,6 +348,8 @@
                 self.LOAD_CONST(oparg, next_instr)
             elif opcode == opcodedesc.LOAD_DEREF.index:
                 self.LOAD_DEREF(oparg, next_instr)
+            elif opcode == opcodedesc.LOAD_CLASSDEREF.index:
+                self.LOAD_CLASSDEREF(oparg, next_instr)
             elif opcode == opcodedesc.LOAD_FAST.index:
                 self.LOAD_FAST(oparg, next_instr)
             elif opcode == opcodedesc.LOAD_GLOBAL.index:
@@ -521,6 +523,18 @@
         else:
             self.pushvalue(w_value)
 
+    def LOAD_CLASSDEREF(self, varindex, next_instr):
+        # like LOAD_DEREF but used in class bodies
+        space = self.space
+        i = varindex - len(self.pycode.co_cellvars)
+        assert i >= 0
+        name = self.pycode.co_freevars[i]
+        w_value = space.finditem(self.debugdata.w_locals, space.wrap(name))
+        if w_value is None:
+            self.LOAD_DEREF(varindex, next_instr)
+        else:
+            self.pushvalue(w_value)
+
     def STORE_DEREF(self, varindex, next_instr):
         # nested scopes: access a variable through its cell object
         w_newvalue = self.popvalue()
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to