[pypy-commit] pypy ast-arena: Some progress. The interpret() tests still don't pass.

amauryfa pypy.commits at gmail.com
Wed Apr 13 14:43:27 EDT 2016


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: ast-arena
Changeset: r83657:6b016173668b
Date: 2016-04-13 20:36 +0200
http://bitbucket.org/pypy/pypy/changeset/6b016173668b/

Log:	Some progress. The interpret() tests still don't pass.

diff --git a/pypy/interpreter/astcompiler/ast.py b/pypy/interpreter/astcompiler/ast.py
--- a/pypy/interpreter/astcompiler/ast.py
+++ b/pypy/interpreter/astcompiler/ast.py
@@ -33,6 +33,9 @@
 class AST(object):
     __metaclass__ = extendabletype
 
+    def __init__(self, arena):
+        pass
+
     def walkabout(self, visitor):
         raise AssertionError("walkabout() implementation not provided")
 
@@ -160,9 +163,6 @@
 
 class mod(AST):
 
-    def __init__(self, arena):
-        pass
-
     @staticmethod
     def from_object(space, arena, w_node):
         if space.is_w(w_node, space.w_None):
@@ -182,8 +182,8 @@
 class Module(mod):
 
     def __init__(self, arena, body):
+        mod.__init__(self, arena)
         self.body = body
-        mod.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_Module(self)
@@ -216,8 +216,8 @@
 class Interactive(mod):
 
     def __init__(self, arena, body):
+        mod.__init__(self, arena)
         self.body = body
-        mod.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_Interactive(self)
@@ -250,8 +250,8 @@
 class Expression(mod):
 
     def __init__(self, arena, body):
+        mod.__init__(self, arena)
         self.body = body
-        mod.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_Expression(self)
@@ -278,8 +278,8 @@
 class Suite(mod):
 
     def __init__(self, arena, body):
+        mod.__init__(self, arena)
         self.body = body
-        mod.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_Suite(self)
@@ -312,6 +312,7 @@
 class stmt(AST):
 
     def __init__(self, arena, lineno, col_offset):
+        AST.__init__(self, arena)
         self.lineno = lineno
         self.col_offset = col_offset
 
@@ -372,11 +373,11 @@
 class FunctionDef(stmt):
 
     def __init__(self, arena, name, args, body, decorator_list, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.name = name
         self.args = args
         self.body = body
         self.decorator_list = decorator_list
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_FunctionDef(self)
@@ -437,11 +438,11 @@
 class ClassDef(stmt):
 
     def __init__(self, arena, name, bases, body, decorator_list, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.name = name
         self.bases = bases
         self.body = body
         self.decorator_list = decorator_list
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_ClassDef(self)
@@ -508,8 +509,8 @@
 class Return(stmt):
 
     def __init__(self, arena, value, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.value = value
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Return(self)
@@ -545,8 +546,8 @@
 class Delete(stmt):
 
     def __init__(self, arena, targets, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.targets = targets
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Delete(self)
@@ -587,9 +588,9 @@
 class Assign(stmt):
 
     def __init__(self, arena, targets, value, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.targets = targets
         self.value = value
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Assign(self)
@@ -635,10 +636,10 @@
 class AugAssign(stmt):
 
     def __init__(self, arena, target, op, value, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.target = target
         self.op = op
         self.value = value
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_AugAssign(self)
@@ -682,10 +683,10 @@
 class Print(stmt):
 
     def __init__(self, arena, dest, values, nl, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.dest = dest
         self.values = values
         self.nl = nl
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Print(self)
@@ -736,11 +737,11 @@
 class For(stmt):
 
     def __init__(self, arena, target, iter, body, orelse, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.target = target
         self.iter = iter
         self.body = body
         self.orelse = orelse
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_For(self)
@@ -802,10 +803,10 @@
 class While(stmt):
 
     def __init__(self, arena, test, body, orelse, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.test = test
         self.body = body
         self.orelse = orelse
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_While(self)
@@ -862,10 +863,10 @@
 class If(stmt):
 
     def __init__(self, arena, test, body, orelse, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.test = test
         self.body = body
         self.orelse = orelse
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_If(self)
@@ -922,10 +923,10 @@
 class With(stmt):
 
     def __init__(self, arena, context_expr, optional_vars, body, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.context_expr = context_expr
         self.optional_vars = optional_vars
         self.body = body
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_With(self)
@@ -977,10 +978,10 @@
 class Raise(stmt):
 
     def __init__(self, arena, type, inst, tback, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.type = type
         self.inst = inst
         self.tback = tback
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Raise(self)
@@ -1028,10 +1029,10 @@
 class TryExcept(stmt):
 
     def __init__(self, arena, body, handlers, orelse, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.body = body
         self.handlers = handlers
         self.orelse = orelse
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_TryExcept(self)
@@ -1094,9 +1095,9 @@
 class TryFinally(stmt):
 
     def __init__(self, arena, body, finalbody, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.body = body
         self.finalbody = finalbody
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_TryFinally(self)
@@ -1148,9 +1149,9 @@
 class Assert(stmt):
 
     def __init__(self, arena, test, msg, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.test = test
         self.msg = msg
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Assert(self)
@@ -1191,8 +1192,8 @@
 class Import(stmt):
 
     def __init__(self, arena, names, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.names = names
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Import(self)
@@ -1233,10 +1234,10 @@
 class ImportFrom(stmt):
 
     def __init__(self, arena, module, names, level, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.module = module
         self.names = names
         self.level = level
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_ImportFrom(self)
@@ -1285,10 +1286,10 @@
 class Exec(stmt):
 
     def __init__(self, arena, body, globals, locals, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.body = body
         self.globals = globals
         self.locals = locals
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Exec(self)
@@ -1335,8 +1336,8 @@
 class Global(stmt):
 
     def __init__(self, arena, names, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.names = names
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Global(self)
@@ -1375,8 +1376,8 @@
 class Expr(stmt):
 
     def __init__(self, arena, value, lineno, col_offset):
+        stmt.__init__(self, arena, lineno, col_offset)
         self.value = value
-        stmt.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Expr(self)
@@ -1501,6 +1502,7 @@
 class expr(AST):
 
     def __init__(self, arena, lineno, col_offset):
+        AST.__init__(self, arena)
         self.lineno = lineno
         self.col_offset = col_offset
 
@@ -1561,9 +1563,9 @@
 class BoolOp(expr):
 
     def __init__(self, arena, op, values, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.op = op
         self.values = values
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_BoolOp(self)
@@ -1608,10 +1610,10 @@
 class BinOp(expr):
 
     def __init__(self, arena, left, op, right, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.left = left
         self.op = op
         self.right = right
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_BinOp(self)
@@ -1655,9 +1657,9 @@
 class UnaryOp(expr):
 
     def __init__(self, arena, op, operand, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.op = op
         self.operand = operand
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_UnaryOp(self)
@@ -1696,9 +1698,9 @@
 class Lambda(expr):
 
     def __init__(self, arena, args, body, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.args = args
         self.body = body
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Lambda(self)
@@ -1738,10 +1740,10 @@
 class IfExp(expr):
 
     def __init__(self, arena, test, body, orelse, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.test = test
         self.body = body
         self.orelse = orelse
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_IfExp(self)
@@ -1786,9 +1788,9 @@
 class Dict(expr):
 
     def __init__(self, arena, keys, values, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.keys = keys
         self.values = values
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Dict(self)
@@ -1840,8 +1842,8 @@
 class Set(expr):
 
     def __init__(self, arena, elts, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.elts = elts
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Set(self)
@@ -1882,9 +1884,9 @@
 class ListComp(expr):
 
     def __init__(self, arena, elt, generators, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.elt = elt
         self.generators = generators
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_ListComp(self)
@@ -1930,9 +1932,9 @@
 class SetComp(expr):
 
     def __init__(self, arena, elt, generators, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.elt = elt
         self.generators = generators
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_SetComp(self)
@@ -1978,10 +1980,10 @@
 class DictComp(expr):
 
     def __init__(self, arena, key, value, generators, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.key = key
         self.value = value
         self.generators = generators
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_DictComp(self)
@@ -2032,9 +2034,9 @@
 class GeneratorExp(expr):
 
     def __init__(self, arena, elt, generators, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.elt = elt
         self.generators = generators
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_GeneratorExp(self)
@@ -2080,8 +2082,8 @@
 class Yield(expr):
 
     def __init__(self, arena, value, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.value = value
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Yield(self)
@@ -2117,10 +2119,10 @@
 class Compare(expr):
 
     def __init__(self, arena, left, ops, comparators, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.left = left
         self.ops = ops
         self.comparators = comparators
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Compare(self)
@@ -2175,12 +2177,12 @@
 class Call(expr):
 
     def __init__(self, arena, func, args, keywords, starargs, kwargs, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.func = func
         self.args = args
         self.keywords = keywords
         self.starargs = starargs
         self.kwargs = kwargs
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Call(self)
@@ -2249,8 +2251,8 @@
 class Repr(expr):
 
     def __init__(self, arena, value, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.value = value
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Repr(self)
@@ -2285,8 +2287,8 @@
 class Num(expr):
 
     def __init__(self, arena, n, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.n = n
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Num(self)
@@ -2320,8 +2322,8 @@
 class Str(expr):
 
     def __init__(self, arena, s, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.s = s
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Str(self)
@@ -2355,10 +2357,10 @@
 class Attribute(expr):
 
     def __init__(self, arena, value, attr, ctx, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.value = value
         self.attr = attr
         self.ctx = ctx
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Attribute(self)
@@ -2401,10 +2403,10 @@
 class Subscript(expr):
 
     def __init__(self, arena, value, slice, ctx, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.value = value
         self.slice = slice
         self.ctx = ctx
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Subscript(self)
@@ -2448,9 +2450,9 @@
 class Name(expr):
 
     def __init__(self, arena, id, ctx, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.id = id
         self.ctx = ctx
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Name(self)
@@ -2488,9 +2490,9 @@
 class List(expr):
 
     def __init__(self, arena, elts, ctx, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.elts = elts
         self.ctx = ctx
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_List(self)
@@ -2535,9 +2537,9 @@
 class Tuple(expr):
 
     def __init__(self, arena, elts, ctx, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.elts = elts
         self.ctx = ctx
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Tuple(self)
@@ -2582,8 +2584,8 @@
 class Const(expr):
 
     def __init__(self, arena, value, lineno, col_offset):
+        expr.__init__(self, arena, lineno, col_offset)
         self.value = value
-        expr.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_Const(self)
@@ -2681,9 +2683,6 @@
 
 class slice(AST):
 
-    def __init__(self, arena):
-        pass
-
     @staticmethod
     def from_object(space, arena, w_node):
         if space.is_w(w_node, space.w_None):
@@ -2723,10 +2722,10 @@
 class Slice(slice):
 
     def __init__(self, arena, lower, upper, step):
+        slice.__init__(self, arena)
         self.lower = lower
         self.upper = upper
         self.step = step
-        slice.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_Slice(self)
@@ -2766,8 +2765,8 @@
 class ExtSlice(slice):
 
     def __init__(self, arena, dims):
+        slice.__init__(self, arena)
         self.dims = dims
-        slice.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_ExtSlice(self)
@@ -2800,8 +2799,8 @@
 class Index(slice):
 
     def __init__(self, arena, value):
+        slice.__init__(self, arena)
         self.value = value
-        slice.__init__(self, arena)
 
     def walkabout(self, visitor):
         visitor.visit_Index(self)
@@ -3124,10 +3123,10 @@
 class comprehension(AST):
 
     def __init__(self, arena, target, iter, ifs):
+        AST.__init__(self, arena)
         self.target = target
         self.iter = iter
         self.ifs = ifs
-        None.__init__(self, arena)
 
     def mutate_over(self, visitor):
         self.target = self.target.mutate_over(visitor)
@@ -3169,6 +3168,7 @@
 class excepthandler(AST):
 
     def __init__(self, arena, lineno, col_offset):
+        AST.__init__(self, arena)
         self.lineno = lineno
         self.col_offset = col_offset
 
@@ -3185,10 +3185,10 @@
 class ExceptHandler(excepthandler):
 
     def __init__(self, arena, type, name, body, lineno, col_offset):
+        excepthandler.__init__(self, arena, lineno, col_offset)
         self.type = type
         self.name = name
         self.body = body
-        excepthandler.__init__(self, arena, lineno, col_offset)
 
     def walkabout(self, visitor):
         visitor.visit_ExceptHandler(self)
@@ -3241,11 +3241,11 @@
 class arguments(AST):
 
     def __init__(self, arena, args, vararg, kwarg, defaults):
+        AST.__init__(self, arena)
         self.args = args
         self.vararg = vararg
         self.kwarg = kwarg
         self.defaults = defaults
-        None.__init__(self, arena)
 
     def mutate_over(self, visitor):
         if self.args:
@@ -3296,9 +3296,9 @@
 class keyword(AST):
 
     def __init__(self, arena, arg, value):
+        AST.__init__(self, arena)
         self.arg = arg
         self.value = value
-        None.__init__(self, arena)
 
     def mutate_over(self, visitor):
         self.value = self.value.mutate_over(visitor)
@@ -3328,9 +3328,9 @@
 class alias(AST):
 
     def __init__(self, arena, name, asname):
+        AST.__init__(self, arena)
         self.name = name
         self.asname = asname
-        None.__init__(self, arena)
 
     def mutate_over(self, visitor):
         return visitor.visit_alias(self)
diff --git a/pypy/interpreter/astcompiler/astarena.py b/pypy/interpreter/astcompiler/astarena.py
--- a/pypy/interpreter/astcompiler/astarena.py
+++ b/pypy/interpreter/astcompiler/astarena.py
@@ -1,2 +1,141 @@
+from rpython.rtyper import rmodel, rclass, rbuiltin
+from rpython.rtyper.extregistry import ExtRegistryEntry
+from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
+from rpython.flowspace.model import Constant
+from rpython.annotator import model as annmodel
+from pypy.interpreter.astcompiler import ast
+from rpython.rlib.rawstorage import alloc_raw_storage
+from rpython.rtyper.annlowlevel import (cast_instance_to_gcref,
+                                        cast_gcref_to_instance)
+
+# This is the most important line!
+ast.AST._alloc_flavor_ = 'raw'
+
 class Arena(object):
-    pass
+    def __init__(self):
+        self.memory_blocks = []
+        self.objects = []
+
+    def allocate(self, cls):
+        xxx
+
+def _all_subclasses(cls):
+    yield cls
+    for subclass in cls.__subclasses__():
+        for c in _all_subclasses(subclass):
+            yield c
+
+
+class SomeAstInstance(annmodel.SomeInstance):
+    def rtyper_makerepr(self, rtyper):
+        return _getinstancerepr(rtyper, self.classdef)
+
+
+class SomeArena(annmodel.SomeInstance):
+    def rtyper_makerepr(self, rtyper):
+        return ArenaRepr()
+
+ARENA = lltype.GcStruct('Arena',
+                        ('storage', llmemory.Address),
+                        ('size', lltype.Signed),
+                        ('current', lltype.Signed),
+                        )
+
+class ArenaRepr(rmodel.Repr):
+    lowleveltype = lltype.Ptr(ARENA)
+
+    def rtyper_new(self, hop):
+        hop.exception_cannot_occur()
+        return hop.gendirectcall(self.ll_new)
+
+    @staticmethod
+    def ll_new():
+        ll_arena = lltype.malloc(ARENA)
+        SIZE = 1000 * 1000
+        ll_arena.storage = llmemory.cast_ptr_to_adr(alloc_raw_storage(
+            SIZE, track_allocation=False, zero=False))
+        ll_arena.size = SIZE
+        ll_arena.current = 0
+        return ll_arena
+
+    @staticmethod
+    def ll_allocate(ll_arena, TYPE):
+        size = 100 #  XXX rffi.sizeof(TYPE.TO)
+        offset = ll_arena.current
+        assert offset + size < ll_arena.size
+        ll_arena.current += size
+        return rffi.cast(TYPE, ll_arena.storage + offset)
+
+class AstNodeRepr(rclass.InstanceRepr):
+    def alloc_instance(self, llops, classcallhop=None, nonmovable=False):
+        if classcallhop is None:
+            raise TyperError("must instantiate %r by calling the class" % (
+                self.classdef,))
+        hop = classcallhop
+        r_arena = hop.args_r[0]
+        v_arena = hop.inputarg(r_arena, 0)
+        v_size = hop.inputconst(lltype.Signed, 
+                                rffi.sizeof(self.lowleveltype))
+        cTYPE = hop.inputconst(lltype.Void, self.lowleveltype)
+        v_ptr = hop.llops.gendirectcall(r_arena.ll_allocate, v_arena, cTYPE)
+        # return rbuiltin.gen_cast(llops, self.lowleveltype, v_ptr)
+        return v_ptr
+
+
+def _getinstancerepr(rtyper, classdef):
+    # Almost a copy of rclass.getinstancerepr()
+    if classdef.basedef:
+        _getinstancerepr(rtyper, classdef.basedef)
+    flavor = rmodel.getgcflavor(classdef)
+    try:
+        result = rtyper.instance_reprs[classdef, flavor]
+    except KeyError:
+        result = AstNodeRepr(rtyper, classdef, gcflavor=flavor)
+
+        rtyper.instance_reprs[classdef, flavor] = result
+        rtyper.add_pendingsetup(result)
+    return result
+
+
+class ArenaEntry(ExtRegistryEntry):
+    _about_ = Arena
+
+    def compute_result_annotation(self):
+        return SomeArena(self.bookkeeper.getuniqueclassdef(Arena))
+
+    def specialize_call(self, hop):
+        return hop.r_result.rtyper_new(hop)
+    
+
+class AstEntry(ExtRegistryEntry):
+    _about_ = tuple(_all_subclasses(ast.AST))
+
+    def compute_result_annotation(self, *args):
+        from rpython.annotator.argument import ArgumentsForTranslation
+        classdef = self.bookkeeper.getuniqueclassdef(self.instance)
+        s_init = classdef.classdesc.s_read_attribute('__init__')
+        s_instance = SomeAstInstance(classdef)
+        self.bookkeeper.emulate_pbc_call(classdef, s_init,
+                                         [s_instance] + list(args))
+        return s_instance
+
+    def specialize_call(self, hop):
+        from rpython.rtyper.rmodel import inputconst
+        from rpython.rtyper.lltypesystem.lltype import Void, Ptr
+        hop.exception_is_here()
+        s_instance = hop.s_result
+        object_type = hop.r_result.object_type
+        classdef = s_instance.classdef
+        rinstance = _getinstancerepr(hop.rtyper, classdef)
+        v_instance = rinstance.new_instance(hop.llops, hop)
+        # Call __init__
+        s_init = classdef.classdesc.s_read_attribute('__init__')
+        v_init = Constant("init-func-dummy")   # this value not really used
+        hop2 = hop.copy()
+        hop2.v_s_insertfirstarg(v_instance, s_instance)  # add 'instance'
+        hop2.v_s_insertfirstarg(v_init, s_init)   # add 'initfunc'
+        hop2.s_result = annmodel.s_None
+        hop2.r_result = hop.rtyper.getrepr(hop2.s_result)
+        hop2.dispatch()
+        return v_instance
+
diff --git a/pypy/interpreter/astcompiler/test/test_arena.py b/pypy/interpreter/astcompiler/test/test_arena.py
new file mode 100644
--- /dev/null
+++ b/pypy/interpreter/astcompiler/test/test_arena.py
@@ -0,0 +1,35 @@
+from rpython.translator.c.test.test_genc import compile
+from rpython.rtyper.test.test_llinterp import interpret
+from pypy.interpreter.astcompiler import ast
+from pypy.interpreter.astcompiler import astarena
+from rpython.rtyper.test.tool import BaseRtypingTest
+
+
+class TestArena(BaseRtypingTest):
+    def test_empty_module(self):
+        def run():
+            arena = astarena.Arena()
+            node = ast.Module(arena, [
+                ast.Name(arena, 'x', ast.Load, 1, 1)])
+            return len(node.body)
+        assert run() == 1
+        assert interpret(run, []) == 1
+        fn = compile(run, [])
+        assert fn() == 1
+
+    def test_compile(self):
+        from pypy.interpreter.pyparser import pyparse
+        from pypy.interpreter.astcompiler import astbuilder
+        from pypy.objspace.fake.objspace import FakeObjSpace
+        space = FakeObjSpace()
+        def run(expr):
+            p = pyparse.PythonParser(space)
+            info = pyparse.CompileInfo("<test>", 'exec')
+            arena = astarena.Arena()
+            cst = p.parse_source(expr, info)
+            ast = astbuilder.ast_from_node(space, arena, cst, info)
+        run("x=2")
+        # res = interpret(run, [self.string_to_ll("x=2")])
+        fn = compile(run, [str])
+        fn("x=2")
+        
diff --git a/pypy/interpreter/astcompiler/tools/asdl_py.py b/pypy/interpreter/astcompiler/tools/asdl_py.py
--- a/pypy/interpreter/astcompiler/tools/asdl_py.py
+++ b/pypy/interpreter/astcompiler/tools/asdl_py.py
@@ -84,15 +84,14 @@
         else:
             self.emit("class %s(AST):" % (base,))
             self.emit("")
-            args = "".join(", " + attr.name.value
-                           for attr in sum.attributes)
-            self.emit("def __init__(self, arena%s):" % (args,), 1)
             if sum.attributes:
+                args = "".join(", " + attr.name.value
+                               for attr in sum.attributes)
+                self.emit("def __init__(self, arena%s):" % (args,), 1)
+                self.emit("AST.__init__(self, arena)", 2)
                 for attr in sum.attributes:
                     self.visit(attr)
-            else:
-                self.emit("pass", 2)
-            self.emit("")
+                self.emit("")
             self.emit("@staticmethod", 1)
             self.emit("def from_object(space, arena, w_node):", 1)
             self.emit("if space.is_w(w_node, space.w_None):", 2)
@@ -215,11 +214,11 @@
             args = "arena" + "".join(", %s" % field.name
                                      for field in arg_fields)
             self.emit("def __init__(self, %s):" % args, 1)
+            base_args = "arena" + "".join(", %s" % field.name
+                                          for field in (extras or ()))
+            self.emit("%s.__init__(self, %s)" % (base or "AST", base_args), 2)
             for field in fields:
                 self.visit(field)
-            base_args = "arena" + "".join(", %s" % field.name
-                                          for field in (extras or ()))
-            self.emit("%s.__init__(self, %s)" % (base, base_args), 2)
     
     def make_mutate_over(self, cons, name):
         self.emit("def mutate_over(self, visitor):", 1)
@@ -420,6 +419,9 @@
 class AST(object):
     __metaclass__ = extendabletype
 
+    def __init__(self, arena):
+        pass
+
     def walkabout(self, visitor):
         raise AssertionError("walkabout() implementation not provided")
 
diff --git a/pypy/objspace/fake/objspace.py b/pypy/objspace/fake/objspace.py
--- a/pypy/objspace/fake/objspace.py
+++ b/pypy/objspace/fake/objspace.py
@@ -413,7 +413,12 @@
     def get(self, name):
         name + "xx"   # check that it's a string
         return w_some_obj()
-FakeObjSpace.sys = FakeModule()
+
+class FakeSysModule(FakeModule):
+    def get_w_default_encoder(self):
+        return w_some_obj()
+
+FakeObjSpace.sys = FakeSysModule()
 FakeObjSpace.sys.filesystemencoding = 'foobar'
 FakeObjSpace.sys.defaultencoding = 'ascii'
 FakeObjSpace.builtin = FakeModule()
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -565,7 +565,7 @@
             clsname = 'object'
         else:
             clsname = self.classdef.name
-        return '<InstanceRepr for %s>' % (clsname,)
+        return '<%s for %s>' % (self.__class__.__name__, clsname,)
 
     def compact_repr(self):
         if self.classdef is None:
@@ -698,8 +698,7 @@
             rbase = rbase.rbase
         return False
 
-    def new_instance(self, llops, classcallhop=None, nonmovable=False):
-        """Build a new instance, without calling __init__."""
+    def alloc_instance(self, llops, classcallhop=None, nonmovable=False):
         flavor = self.gcflavor
         flags = {'flavor': flavor}
         if nonmovable:
@@ -709,6 +708,11 @@
         vlist = [ctype, cflags]
         vptr = llops.genop('malloc', vlist,
                            resulttype=Ptr(self.object_type))
+        return vptr
+
+    def new_instance(self, llops, classcallhop=None, nonmovable=False):
+        """Build a new instance, without calling __init__."""
+        vptr = self.alloc_instance(llops, classcallhop, nonmovable=nonmovable)
         ctypeptr = inputconst(CLASSTYPE, self.rclass.getvtable())
         self.setfield(vptr, '__class__', ctypeptr, llops)
         # initialize instance attributes from their defaults from the class


More information about the pypy-commit mailing list