[pypy-commit] pypy default: (ronan mostly) merging translation-cleanup branch, where we split
fijal
noreply at buildbot.pypy.org
Sun Oct 21 17:16:56 CEST 2012
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch:
Changeset: r58318:3fdbd7395926
Date: 2012-10-21 17:16 +0200
http://bitbucket.org/pypy/pypy/changeset/3fdbd7395926/
Log: (ronan mostly) merging translation-cleanup branch, where we split
interpreter and the RPython compilation toolchain
diff too long, truncating to 2000 out of 2672 lines
diff --git a/pypy/annotation/binaryop.py b/pypy/annotation/binaryop.py
--- a/pypy/annotation/binaryop.py
+++ b/pypy/annotation/binaryop.py
@@ -31,21 +31,21 @@
# XXX unify this with ObjSpace.MethodTable
BINARY_OPERATIONS = set(['add', 'sub', 'mul', 'div', 'mod',
- 'truediv', 'floordiv', 'divmod', 'pow',
+ 'truediv', 'floordiv', 'divmod',
'and_', 'or_', 'xor',
'lshift', 'rshift',
'getitem', 'setitem', 'delitem',
'getitem_idx', 'getitem_key', 'getitem_idx_key',
'inplace_add', 'inplace_sub', 'inplace_mul',
'inplace_truediv', 'inplace_floordiv', 'inplace_div',
- 'inplace_mod', 'inplace_pow',
+ 'inplace_mod',
'inplace_lshift', 'inplace_rshift',
'inplace_and', 'inplace_or', 'inplace_xor',
'lt', 'le', 'eq', 'ne', 'gt', 'ge', 'is_', 'cmp',
'coerce',
]
+[opname+'_ovf' for opname in
- """add sub mul floordiv div mod pow lshift
+ """add sub mul floordiv div mod lshift
""".split()
])
@@ -65,7 +65,6 @@
def inplace_floordiv((obj1, obj2)): return pair(obj1, obj2).floordiv()
def inplace_div((obj1, obj2)): return pair(obj1, obj2).div()
def inplace_mod((obj1, obj2)): return pair(obj1, obj2).mod()
- def inplace_pow((obj1, obj2)): return pair(obj1, obj2).pow(s_None)
def inplace_lshift((obj1, obj2)): return pair(obj1, obj2).lshift()
def inplace_rshift((obj1, obj2)): return pair(obj1, obj2).rshift()
def inplace_and((obj1, obj2)): return pair(obj1, obj2).and_()
@@ -301,19 +300,6 @@
return SomeInteger(nonneg=int1.nonneg, knowntype=int1.knowntype)
rshift.can_only_throw = []
- def pow((int1, int2), obj3):
- knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
- return SomeInteger(nonneg = int1.nonneg,
- knowntype=knowntype)
- pow.can_only_throw = [ZeroDivisionError]
- pow_ovf = _clone(pow, [ZeroDivisionError, OverflowError])
-
- def inplace_pow((int1, int2)):
- knowntype = rarithmetic.compute_restype(int1.knowntype, int2.knowntype)
- return SomeInteger(nonneg = int1.nonneg,
- knowntype=knowntype)
- inplace_pow.can_only_throw = [ZeroDivisionError]
-
def _compare_helper((int1, int2), opname, operation):
r = SomeBool()
if int1.is_immutable_constant() and int2.is_immutable_constant():
@@ -500,9 +486,6 @@
div.can_only_throw = []
truediv = div
- def pow((flt1, flt2), obj3):
- raise NotImplementedError("float power not supported, use math.pow")
-
# repeat these in order to copy the 'can_only_throw' attribute
inplace_div = div
inplace_truediv = truediv
diff --git a/pypy/annotation/bookkeeper.py b/pypy/annotation/bookkeeper.py
--- a/pypy/annotation/bookkeeper.py
+++ b/pypy/annotation/bookkeeper.py
@@ -16,7 +16,7 @@
from pypy.annotation.dictdef import DictDef
from pypy.annotation import description
from pypy.annotation.signature import annotationoftype
-from pypy.interpreter.argument import ArgumentsForTranslation
+from pypy.objspace.flow.argument import ArgumentsForTranslation
from pypy.rlib.objectmodel import r_dict, Symbolic
from pypy.tool.algo.unionfind import UnionFind
from pypy.rpython.lltypesystem import lltype, llmemory
@@ -101,7 +101,7 @@
def consider_list_delitem(self, idx):
return self.indexrepr(idx)
-
+
def consider_str_join(self, s):
if s.is_constant():
return repr(s.const)
@@ -224,7 +224,7 @@
check_no_flags(s_value_or_def.listdef.listitem)
elif isinstance(s_value_or_def, SomeDict):
check_no_flags(s_value_or_def.dictdef.dictkey)
- check_no_flags(s_value_or_def.dictdef.dictvalue)
+ check_no_flags(s_value_or_def.dictdef.dictvalue)
elif isinstance(s_value_or_def, SomeTuple):
for s_item in s_value_or_def.items:
check_no_flags(s_item)
@@ -238,9 +238,9 @@
elif isinstance(s_value_or_def, ListItem):
if s_value_or_def in seen:
return
- seen.add(s_value_or_def)
+ seen.add(s_value_or_def)
check_no_flags(s_value_or_def.s_value)
-
+
for clsdef in self.classdefs:
check_no_flags(clsdef)
@@ -366,14 +366,14 @@
listdef = ListDef(self, s_ImpossibleValue)
for e in x:
listdef.generalize(self.immutablevalue(e, False))
- result = SomeList(listdef)
+ result = SomeList(listdef)
elif tp is dict or tp is r_dict:
if need_const:
key = Constant(x)
try:
return self.immutable_cache[key]
except KeyError:
- result = SomeDict(DictDef(self,
+ result = SomeDict(DictDef(self,
s_ImpossibleValue,
s_ImpossibleValue,
is_r_dict = tp is r_dict))
@@ -396,7 +396,7 @@
result.const_box = key
return result
else:
- dictdef = DictDef(self,
+ dictdef = DictDef(self,
s_ImpossibleValue,
s_ImpossibleValue,
is_r_dict = tp is r_dict)
@@ -545,7 +545,7 @@
return True
else:
return False
-
+
def getfrozen(self, pyobj):
return description.FrozenDesc(self, pyobj)
@@ -566,7 +566,7 @@
key = (x.__class__, x)
if key in self.seen_mutable:
return
- clsdef = self.getuniqueclassdef(x.__class__)
+ clsdef = self.getuniqueclassdef(x.__class__)
self.seen_mutable[key] = True
self.event('mutable', x)
source = InstanceSource(self, x)
@@ -586,7 +586,7 @@
except KeyError:
access_sets = map[attrname] = UnionFind(description.ClassAttrFamily)
return access_sets
-
+
def pbc_getattr(self, pbc, s_attr):
assert s_attr.is_constant()
attr = s_attr.const
@@ -598,7 +598,7 @@
first = descs[0]
if len(descs) == 1:
return first.s_read_attribute(attr)
-
+
change = first.mergeattrfamilies(descs[1:], attr)
attrfamily = first.getattrfamily(attr)
@@ -700,7 +700,7 @@
def ondegenerated(self, what, s_value, where=None, called_from_graph=None):
self.annotator.ondegenerated(what, s_value, where=where,
called_from_graph=called_from_graph)
-
+
def whereami(self):
return self.annotator.whereami(self.position_key)
diff --git a/pypy/annotation/description.py b/pypy/annotation/description.py
--- a/pypy/annotation/description.py
+++ b/pypy/annotation/description.py
@@ -1,8 +1,7 @@
import types, py
from pypy.objspace.flow.model import Constant, FunctionGraph
-from pypy.interpreter.pycode import cpython_code_signature
-from pypy.interpreter.argument import rawshape
-from pypy.interpreter.argument import ArgErr
+from pypy.objspace.flow.bytecode import cpython_code_signature
+from pypy.objspace.flow.argument import rawshape, ArgErr
from pypy.tool.sourcetools import valid_identifier
from pypy.tool.pairtype import extendabletype
@@ -181,7 +180,7 @@
name = pyobj.func_name
if signature is None:
if hasattr(pyobj, '_generator_next_method_of_'):
- from pypy.interpreter.argument import Signature
+ from pypy.objspace.flow.argument import Signature
signature = Signature(['entry']) # haaaaaack
defaults = ()
else:
@@ -260,7 +259,7 @@
try:
inputcells = args.match_signature(signature, defs_s)
except ArgErr, e:
- raise TypeError("signature mismatch: %s() %s" %
+ raise TypeError("signature mismatch: %s() %s" %
(self.name, e.getmsg()))
return inputcells
diff --git a/pypy/annotation/specialize.py b/pypy/annotation/specialize.py
--- a/pypy/annotation/specialize.py
+++ b/pypy/annotation/specialize.py
@@ -6,7 +6,7 @@
from pypy.objspace.flow.model import Block, Link, Variable, SpaceOperation
from pypy.objspace.flow.model import Constant, checkgraph
from pypy.annotation import model as annmodel
-from pypy.interpreter.argument import Signature
+from pypy.objspace.flow.argument import Signature
def flatten_star_args(funcdesc, args_s):
argnames, vararg, kwarg = funcdesc.signature
diff --git a/pypy/annotation/test/test_annrpython.py b/pypy/annotation/test/test_annrpython.py
--- a/pypy/annotation/test/test_annrpython.py
+++ b/pypy/annotation/test/test_annrpython.py
@@ -13,7 +13,7 @@
from pypy.rlib.rarithmetic import r_uint, base_int, r_longlong, r_ulonglong
from pypy.rlib.rarithmetic import r_singlefloat
from pypy.rlib import objectmodel
-from pypy.objspace.flow.objspace import FlowObjSpace
+from pypy.objspace.flow.objspace import FlowObjSpace, FlowingError
from pypy.translator.test import snippet
@@ -1431,15 +1431,6 @@
assert a.binding(et) == t
assert isinstance(a.binding(ev), annmodel.SomeInstance) and a.binding(ev).classdef == a.bookkeeper.getuniqueclassdef(Exception)
- def test_pow(self):
- def f(n):
- n **= 2
- return 2 ** n
- a = self.RPythonAnnotator()
- s = a.build_types(f, [int])
- # result should be an integer
- assert s.knowntype == int
-
def test_inplace_div(self):
def f(n):
n /= 2
@@ -3156,10 +3147,9 @@
x **= y
return x ** y
a = self.RPythonAnnotator()
- s = a.build_types(f, [int, int])
- assert isinstance(s, annmodel.SomeInteger)
- a = self.RPythonAnnotator()
- py.test.raises(NotImplementedError, a.build_types, f, [float, float])
+ py.test.raises(FlowingError, a.build_types, f, [int, int])
+ a = self.RPythonAnnotator()
+ py.test.raises(FlowingError, a.build_types, f, [float, float])
def test_intcmp_bug(self):
def g(x, y):
diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -504,149 +504,6 @@
w_key = keyword_names_w[i - limit]
space.setitem(w_kwds, w_key, keywords_w[i])
-class ArgumentsForTranslation(Arguments):
- def __init__(self, space, args_w, keywords=None, keywords_w=None,
- w_stararg=None, w_starstararg=None):
- self.w_stararg = w_stararg
- self.w_starstararg = w_starstararg
- self.combine_has_happened = False
- Arguments.__init__(self, space, args_w, keywords, keywords_w)
-
- def combine_if_necessary(self):
- if self.combine_has_happened:
- return
- self._combine_wrapped(self.w_stararg, self.w_starstararg)
- self.combine_has_happened = True
-
- def prepend(self, w_firstarg): # used often
- "Return a new Arguments with a new argument inserted first."
- return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w,
- self.keywords, self.keywords_w, self.w_stararg,
- self.w_starstararg)
-
- def copy(self):
- return ArgumentsForTranslation(self.space, self.arguments_w,
- self.keywords, self.keywords_w, self.w_stararg,
- self.w_starstararg)
-
-
-
- def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None,
- blindargs=0):
- self.combine_if_necessary()
- # _match_signature is destructive
- return Arguments._match_signature(
- self, w_firstarg, scope_w, signature,
- defaults_w, blindargs)
-
- def unpack(self):
- self.combine_if_necessary()
- return Arguments.unpack(self)
-
- def match_signature(self, signature, defaults_w):
- """Parse args and kwargs according to the signature of a code object,
- or raise an ArgErr in case of failure.
- """
- return self._parse(None, signature, defaults_w)
-
- def unmatch_signature(self, signature, data_w):
- """kind of inverse of match_signature"""
- args_w, kwds_w = self.unpack()
- need_cnt = len(args_w)
- need_kwds = kwds_w.keys()
- space = self.space
- argnames, varargname, kwargname = signature
- cnt = len(argnames)
- data_args_w = data_w[:cnt]
- if varargname:
- data_w_stararg = data_w[cnt]
- cnt += 1
- else:
- data_w_stararg = space.newtuple([])
-
- unfiltered_kwds_w = {}
- if kwargname:
- data_w_starargarg = data_w[cnt]
- for w_key in space.unpackiterable(data_w_starargarg):
- key = space.str_w(w_key)
- w_value = space.getitem(data_w_starargarg, w_key)
- unfiltered_kwds_w[key] = w_value
- cnt += 1
- assert len(data_w) == cnt
-
- ndata_args_w = len(data_args_w)
- if ndata_args_w >= need_cnt:
- args_w = data_args_w[:need_cnt]
- for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]):
- unfiltered_kwds_w[argname] = w_arg
- assert not space.is_true(data_w_stararg)
- else:
- stararg_w = space.unpackiterable(data_w_stararg)
- datalen = len(data_args_w)
- args_w = [None] * (datalen + len(stararg_w))
- for i in range(0, datalen):
- args_w[i] = data_args_w[i]
- for i in range(0, len(stararg_w)):
- args_w[i + datalen] = stararg_w[i]
- assert len(args_w) == need_cnt
-
- keywords = []
- keywords_w = []
- for key in need_kwds:
- keywords.append(key)
- keywords_w.append(unfiltered_kwds_w[key])
-
- return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w)
-
- @staticmethod
- def frompacked(space, w_args=None, w_kwds=None):
- raise NotImplementedError("go away")
-
- @staticmethod
- def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w):
- args_w = data_w[:shape_cnt]
- p = end_keys = shape_cnt + len(shape_keys)
- if shape_star:
- w_star = data_w[p]
- p += 1
- else:
- w_star = None
- if shape_stst:
- w_starstar = data_w[p]
- p += 1
- else:
- w_starstar = None
- return ArgumentsForTranslation(space, args_w, list(shape_keys),
- data_w[shape_cnt:end_keys], w_star,
- w_starstar)
-
- def flatten(self):
- """ Argument <-> list of w_objects together with "shape" information """
- shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape()
- data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)]
- for key in shape_keys]
- if shape_star:
- data_w.append(self.w_stararg)
- if shape_stst:
- data_w.append(self.w_starstararg)
- return (shape_cnt, shape_keys, shape_star, shape_stst), data_w
-
- def _rawshape(self, nextra=0):
- assert not self.combine_has_happened
- shape_cnt = len(self.arguments_w)+nextra # Number of positional args
- if self.keywords:
- shape_keys = self.keywords[:] # List of keywords (strings)
- shape_keys.sort()
- else:
- shape_keys = []
- shape_star = self.w_stararg is not None # Flag: presence of *arg
- shape_stst = self.w_starstararg is not None # Flag: presence of **kwds
- return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted
-
-def rawshape(args, nextra=0):
- return args._rawshape(nextra)
-
-
#
# ArgErr family of exceptions raised in case of argument mismatch.
# We try to give error messages following CPython's, which are very informative.
diff --git a/pypy/interpreter/test/test_argument.py b/pypy/interpreter/test/test_argument.py
--- a/pypy/interpreter/test/test_argument.py
+++ b/pypy/interpreter/test/test_argument.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
import py
-from pypy.interpreter.argument import (Arguments, ArgumentsForTranslation,
- ArgErr, ArgErrUnknownKwds, ArgErrMultipleValues, ArgErrCount, rawshape,
- Signature)
+from pypy.interpreter.argument import (Arguments, ArgErr, ArgErrUnknownKwds,
+ ArgErrMultipleValues, ArgErrCount, Signature)
from pypy.interpreter.error import OperationError
@@ -687,206 +686,3 @@
def f(x): pass
e = raises(TypeError, "f(**{u'ü' : 19})")
assert "?" in str(e.value)
-
-def make_arguments_for_translation(space, args_w, keywords_w={},
- w_stararg=None, w_starstararg=None):
- return ArgumentsForTranslation(space, args_w, keywords_w.keys(),
- keywords_w.values(), w_stararg,
- w_starstararg)
-
-class TestArgumentsForTranslation(object):
-
- def test_prepend(self):
- space = DummySpace()
- args = ArgumentsForTranslation(space, ["0"])
- args1 = args.prepend("thingy")
- assert args1 is not args
- assert args1.arguments_w == ["thingy", "0"]
- assert args1.keywords is args.keywords
- assert args1.keywords_w is args.keywords_w
-
- def test_unmatch_signature(self):
- space = DummySpace()
- args = make_arguments_for_translation(space, [1,2,3])
- sig = Signature(['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1])
- sig = Signature(['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [2, 3])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1,2,3,4,5])
- sig = Signature(['a', 'b', 'c'], 'r', None)
- data = args.match_signature(sig, [])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
- sig = Signature(['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1], {'c': 5})
- sig = Signature(['a', 'b', 'c'], None, None)
- data = args.match_signature(sig, [2, 3])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
- sig = Signature(['a', 'b', 'c'], None, 'kw')
- data = args.match_signature(sig, [2, 3])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
- sig = Signature(['a', 'b', 'c'], 'r', 'kw')
- data = args.match_signature(sig, [2, 3])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [], {},
- w_stararg=[1],
- w_starstararg={'c': 5, 'd': 7})
- sig = Signature(['a', 'b', 'c'], None, 'kw')
- data = args.match_signature(sig, [2, 3])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- args = make_arguments_for_translation(space, [1,2], {'g': 9},
- w_stararg=[3,4,5],
- w_starstararg={'e': 5, 'd': 7})
- sig = Signature(['a', 'b', 'c'], 'r', 'kw')
- data = args.match_signature(sig, [2, 3])
- new_args = args.unmatch_signature(sig, data)
- assert args.unpack() == new_args.unpack()
-
- def test_rawshape(self):
- space = DummySpace()
- args = make_arguments_for_translation(space, [1,2,3])
- assert rawshape(args) == (3, (), False, False)
-
- args = make_arguments_for_translation(space, [1])
- assert rawshape(args, 2) == (3, (), False, False)
-
- args = make_arguments_for_translation(space, [1,2,3,4,5])
- assert rawshape(args) == (5, (), False, False)
-
- args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
- assert rawshape(args) == (1, ('b', 'c'), False, False)
-
- args = make_arguments_for_translation(space, [1], {'c': 5})
- assert rawshape(args) == (1, ('c', ), False, False)
-
- args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
- assert rawshape(args) == (1, ('c', 'd'), False, False)
-
- args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
- assert rawshape(args) == (5, ('d', 'e'), False, False)
-
- args = make_arguments_for_translation(space, [], {},
- w_stararg=[1],
- w_starstararg={'c': 5, 'd': 7})
- assert rawshape(args) == (0, (), True, True)
-
- args = make_arguments_for_translation(space, [1,2], {'g': 9},
- w_stararg=[3,4,5],
- w_starstararg={'e': 5, 'd': 7})
- assert rawshape(args) == (2, ('g', ), True, True)
-
- def test_copy_and_shape(self):
- space = DummySpace()
- args = ArgumentsForTranslation(space, ['a'], ['x'], [1],
- ['w1'], {'y': 'w2'})
- args1 = args.copy()
- args.combine_if_necessary()
- assert rawshape(args1) == (1, ('x',), True, True)
-
-
- def test_flatten(self):
- space = DummySpace()
- args = make_arguments_for_translation(space, [1,2,3])
- assert args.flatten() == ((3, (), False, False), [1, 2, 3])
-
- args = make_arguments_for_translation(space, [1])
- assert args.flatten() == ((1, (), False, False), [1])
-
- args = make_arguments_for_translation(space, [1,2,3,4,5])
- assert args.flatten() == ((5, (), False, False), [1,2,3,4,5])
-
- args = make_arguments_for_translation(space, [1], {'c': 3, 'b': 2})
- assert args.flatten() == ((1, ('b', 'c'), False, False), [1, 2, 3])
-
- args = make_arguments_for_translation(space, [1], {'c': 5})
- assert args.flatten() == ((1, ('c', ), False, False), [1, 5])
-
- args = make_arguments_for_translation(space, [1], {'c': 5, 'd': 7})
- assert args.flatten() == ((1, ('c', 'd'), False, False), [1, 5, 7])
-
- args = make_arguments_for_translation(space, [1,2,3,4,5], {'e': 5, 'd': 7})
- assert args.flatten() == ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5])
-
- args = make_arguments_for_translation(space, [], {},
- w_stararg=[1],
- w_starstararg={'c': 5, 'd': 7})
- assert args.flatten() == ((0, (), True, True), [[1], {'c': 5, 'd': 7}])
-
- args = make_arguments_for_translation(space, [1,2], {'g': 9},
- w_stararg=[3,4,5],
- w_starstararg={'e': 5, 'd': 7})
- assert args.flatten() == ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}])
-
- def test_stararg_flowspace_variable(self):
- space = DummySpace()
- var = object()
- shape = ((2, ('g', ), True, False), [1, 2, 9, var])
- args = make_arguments_for_translation(space, [1,2], {'g': 9},
- w_stararg=var)
- assert args.flatten() == shape
-
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
-
- def test_fromshape(self):
- space = DummySpace()
- shape = ((3, (), False, False), [1, 2, 3])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((1, (), False, False), [1])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((5, (), False, False), [1,2,3,4,5])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((1, ('b', 'c'), False, False), [1, 2, 3])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((1, ('c', ), False, False), [1, 5])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((1, ('c', 'd'), False, False), [1, 5, 7])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((5, ('d', 'e'), False, False), [1, 2, 3, 4, 5, 7, 5])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((0, (), True, True), [[1], {'c': 5, 'd': 7}])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
- shape = ((2, ('g', ), True, True), [1, 2, 9, [3, 4, 5], {'e': 5, 'd': 7}])
- args = ArgumentsForTranslation.fromshape(space, *shape)
- assert args.flatten() == shape
-
diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py
new file mode 100644
--- /dev/null
+++ b/pypy/objspace/flow/argument.py
@@ -0,0 +1,498 @@
+"""
+Arguments objects.
+"""
+
+class Signature(object):
+ _immutable_ = True
+ _immutable_fields_ = ["argnames[*]"]
+ __slots__ = ("argnames", "varargname", "kwargname")
+
+ def __init__(self, argnames, varargname=None, kwargname=None):
+ self.argnames = argnames
+ self.varargname = varargname
+ self.kwargname = kwargname
+
+ def find_argname(self, name):
+ try:
+ return self.argnames.index(name)
+ except ValueError:
+ return -1
+
+ def num_argnames(self):
+ return len(self.argnames)
+
+ def has_vararg(self):
+ return self.varargname is not None
+
+ def has_kwarg(self):
+ return self.kwargname is not None
+
+ def scope_length(self):
+ scopelen = len(self.argnames)
+ scopelen += self.has_vararg()
+ scopelen += self.has_kwarg()
+ return scopelen
+
+ def getallvarnames(self):
+ argnames = self.argnames
+ if self.varargname is not None:
+ argnames = argnames + [self.varargname]
+ if self.kwargname is not None:
+ argnames = argnames + [self.kwargname]
+ return argnames
+
+ def __repr__(self):
+ return "Signature(%r, %r, %r)" % (
+ self.argnames, self.varargname, self.kwargname)
+
+ def __eq__(self, other):
+ if not isinstance(other, Signature):
+ return NotImplemented
+ return (self.argnames == other.argnames and
+ self.varargname == other.varargname and
+ self.kwargname == other.kwargname)
+
+ def __ne__(self, other):
+ if not isinstance(other, Signature):
+ return NotImplemented
+ return not self == other
+
+
+ # make it look tuply for its use in the annotator
+
+ def __len__(self):
+ return 3
+
+ def __getitem__(self, i):
+ if i == 0:
+ return self.argnames
+ if i == 1:
+ return self.varargname
+ if i == 2:
+ return self.kwargname
+ raise IndexError
+
+class ArgumentsForTranslation(object):
+ def __init__(self, space, args_w, keywords=None, keywords_w=None,
+ w_stararg=None, w_starstararg=None):
+ self.w_stararg = w_stararg
+ self.w_starstararg = w_starstararg
+ self.combine_has_happened = False
+ self.space = space
+ assert isinstance(args_w, list)
+ self.arguments_w = args_w
+ self.keywords = keywords
+ self.keywords_w = keywords_w
+ self.keyword_names_w = None
+
+ def __repr__(self):
+ """ NOT_RPYTHON """
+ name = self.__class__.__name__
+ if not self.keywords:
+ return '%s(%s)' % (name, self.arguments_w,)
+ else:
+ return '%s(%s, %s, %s)' % (name, self.arguments_w,
+ self.keywords, self.keywords_w)
+
+ def _combine_wrapped(self, w_stararg, w_starstararg):
+ "unpack the *arg and **kwd into arguments_w and keywords_w"
+ if w_stararg is not None:
+ self._combine_starargs_wrapped(w_stararg)
+ if w_starstararg is not None:
+ self._combine_starstarargs_wrapped(w_starstararg)
+
+ def _combine_starargs_wrapped(self, w_stararg):
+ # unpack the * arguments
+ space = self.space
+ args_w = space.unpackiterable(w_stararg)
+ self.arguments_w = self.arguments_w + args_w
+
+ def _combine_starstarargs_wrapped(self, w_starstararg):
+ # unpack the ** arguments
+ space = self.space
+ keywords, values_w = space.view_as_kwargs(w_starstararg)
+ if keywords is not None: # this path also taken for empty dicts
+ if self.keywords is None:
+ self.keywords = keywords
+ self.keywords_w = values_w
+ else:
+ if set(keywords) & set(self.keywords):
+ raise TypeError("got multiple values for keyword arguments '%s'", set(keywords) & set(self.keywords))
+ self.keywords = self.keywords + keywords
+ self.keywords_w = self.keywords_w + values_w
+ return
+ if space.isinstance_w(w_starstararg, space.w_dict):
+ keys_w = space.unpackiterable(w_starstararg)
+ else:
+ w_keys = space.call_method(w_starstararg, "keys")
+ keys_w = space.unpackiterable(w_keys)
+ keywords_w = [None] * len(keys_w)
+ keywords = [None] * len(keys_w)
+ for i, w_key in enumerate(keys_w):
+ key = space.str_w(w_key)
+ if key in self.keywords:
+ raise TypeError("got multiple values for keyword argument '%s'" % key)
+ keywords[i] = key
+ keywords_w[i] = space.getitem(w_starstararg, w_key)
+ self.keyword_names_w = keys_w
+ if self.keywords is None:
+ self.keywords = keywords
+ self.keywords_w = keywords_w
+ else:
+ self.keywords = self.keywords + keywords
+ self.keywords_w = self.keywords_w + keywords_w
+
+
+ def fixedunpack(self, argcount):
+ """The simplest argument parsing: get the 'argcount' arguments,
+ or raise a real ValueError if the length is wrong."""
+ if self.keywords:
+ raise ValueError, "no keyword arguments expected"
+ if len(self.arguments_w) > argcount:
+ raise ValueError, "too many arguments (%d expected)" % argcount
+ elif len(self.arguments_w) < argcount:
+ raise ValueError, "not enough arguments (%d expected)" % argcount
+ return self.arguments_w
+
+ def combine_if_necessary(self):
+ if self.combine_has_happened:
+ return
+ self._combine_wrapped(self.w_stararg, self.w_starstararg)
+ self.combine_has_happened = True
+
+ def prepend(self, w_firstarg): # used often
+ "Return a new Arguments with a new argument inserted first."
+ return ArgumentsForTranslation(self.space, [w_firstarg] + self.arguments_w,
+ self.keywords, self.keywords_w, self.w_stararg,
+ self.w_starstararg)
+
+ def copy(self):
+ return ArgumentsForTranslation(self.space, self.arguments_w,
+ self.keywords, self.keywords_w, self.w_stararg,
+ self.w_starstararg)
+
+ def _match_signature(self, scope_w, signature, defaults_w=None):
+ """Parse args and kwargs according to the signature of a code object,
+ or raise an ArgErr in case of failure.
+ """
+ # args_w = list of the normal actual parameters, wrapped
+ # scope_w = resulting list of wrapped values
+ #
+ self.combine_if_necessary()
+ co_argcount = signature.num_argnames() # expected formal arguments, without */**
+
+ args_w = self.arguments_w
+ num_args = len(args_w)
+ keywords = self.keywords or []
+ num_kwds = len(keywords)
+
+ # put as many positional input arguments into place as available
+ take = min(num_args, co_argcount)
+ scope_w[:take] = args_w[:take]
+ input_argcount = take
+
+ # collect extra positional arguments into the *vararg
+ if signature.has_vararg():
+ if num_args > co_argcount:
+ starargs_w = args_w[co_argcount:]
+ else:
+ starargs_w = []
+ scope_w[co_argcount] = self.space.newtuple(starargs_w)
+ elif num_args > co_argcount:
+ raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0)
+
+ # if a **kwargs argument is needed, create the dict
+ w_kwds = None
+ if signature.has_kwarg():
+ w_kwds = self.space.newdict(kwargs=True)
+ scope_w[co_argcount + signature.has_vararg()] = w_kwds
+
+ # handle keyword arguments
+ num_remainingkwds = 0
+ keywords_w = self.keywords_w
+ kwds_mapping = None
+ if num_kwds:
+ # kwds_mapping maps target indexes in the scope (minus input_argcount)
+ # to positions in the keywords_w list
+ kwds_mapping = [-1] * (co_argcount - input_argcount)
+ # match the keywords given at the call site to the argument names
+ # the called function takes
+ # this function must not take a scope_w, to make the scope not
+ # escape
+ num_remainingkwds = len(keywords)
+ for i, name in enumerate(keywords):
+ # If name was not encoded as a string, it could be None. In that
+ # case, it's definitely not going to be in the signature.
+ if name is None:
+ continue
+ j = signature.find_argname(name)
+ # if j == -1 nothing happens
+ if j < input_argcount:
+ # check that no keyword argument conflicts with these.
+ if j >= 0:
+ raise ArgErrMultipleValues(name)
+ else:
+ kwds_mapping[j - input_argcount] = i # map to the right index
+ num_remainingkwds -= 1
+
+ if num_remainingkwds:
+ if w_kwds is not None:
+ # collect extra keyword arguments into the **kwarg
+ limit = len(keywords)
+ if self.keyword_names_w is not None:
+ limit -= len(self.keyword_names_w)
+ for i in range(len(keywords)):
+ if i in kwds_mapping:
+ continue
+ if i < limit:
+ w_key = self.space.wrap(keywords[i])
+ else:
+ w_key = self.keyword_names_w[i - limit]
+ self.space.setitem(w_kwds, w_key, keywords_w[i])
+ else:
+ if co_argcount == 0:
+ raise ArgErrCount(num_args, num_kwds, signature, defaults_w, 0)
+ raise ArgErrUnknownKwds(self.space, num_remainingkwds, keywords,
+ kwds_mapping, self.keyword_names_w)
+
+ # check for missing arguments and fill them from the kwds,
+ # or with defaults, if available
+ missing = 0
+ if input_argcount < co_argcount:
+ def_first = co_argcount - (0 if defaults_w is None else len(defaults_w))
+ j = 0
+ kwds_index = -1
+ for i in range(input_argcount, co_argcount):
+ if kwds_mapping is not None:
+ kwds_index = kwds_mapping[j]
+ j += 1
+ if kwds_index >= 0:
+ scope_w[i] = keywords_w[kwds_index]
+ continue
+ defnum = i - def_first
+ if defnum >= 0:
+ scope_w[i] = defaults_w[defnum]
+ else:
+ missing += 1
+ if missing:
+ raise ArgErrCount(num_args, num_kwds, signature, defaults_w, missing)
+
+ def unpack(self):
+ "Return a ([w1,w2...], {'kw':w3...}) pair."
+ self.combine_if_necessary()
+ kwds_w = {}
+ if self.keywords:
+ for i in range(len(self.keywords)):
+ kwds_w[self.keywords[i]] = self.keywords_w[i]
+ return self.arguments_w, kwds_w
+
+
+ def match_signature(self, signature, defaults_w):
+ """Parse args and kwargs according to the signature of a code object,
+ or raise an ArgErr in case of failure.
+ """
+ scopelen = signature.scope_length()
+ scope_w = [None] * scopelen
+ self._match_signature(scope_w, signature, defaults_w)
+ return scope_w
+
+ def unmatch_signature(self, signature, data_w):
+ """kind of inverse of match_signature"""
+ args_w, kwds_w = self.unpack()
+ need_cnt = len(args_w)
+ need_kwds = kwds_w.keys()
+ space = self.space
+ argnames, varargname, kwargname = signature
+ cnt = len(argnames)
+ data_args_w = data_w[:cnt]
+ if varargname:
+ data_w_stararg = data_w[cnt]
+ cnt += 1
+ else:
+ data_w_stararg = space.newtuple([])
+
+ unfiltered_kwds_w = {}
+ if kwargname:
+ data_w_starargarg = data_w[cnt]
+ for w_key in space.unpackiterable(data_w_starargarg):
+ key = space.str_w(w_key)
+ w_value = space.getitem(data_w_starargarg, w_key)
+ unfiltered_kwds_w[key] = w_value
+ cnt += 1
+ assert len(data_w) == cnt
+
+ ndata_args_w = len(data_args_w)
+ if ndata_args_w >= need_cnt:
+ args_w = data_args_w[:need_cnt]
+ for argname, w_arg in zip(argnames[need_cnt:], data_args_w[need_cnt:]):
+ unfiltered_kwds_w[argname] = w_arg
+ assert not space.is_true(data_w_stararg)
+ else:
+ stararg_w = space.unpackiterable(data_w_stararg)
+ datalen = len(data_args_w)
+ args_w = [None] * (datalen + len(stararg_w))
+ for i in range(0, datalen):
+ args_w[i] = data_args_w[i]
+ for i in range(0, len(stararg_w)):
+ args_w[i + datalen] = stararg_w[i]
+ assert len(args_w) == need_cnt
+
+ keywords = []
+ keywords_w = []
+ for key in need_kwds:
+ keywords.append(key)
+ keywords_w.append(unfiltered_kwds_w[key])
+
+ return ArgumentsForTranslation(self.space, args_w, keywords, keywords_w)
+
+ @staticmethod
+ def fromshape(space, (shape_cnt,shape_keys,shape_star,shape_stst), data_w):
+ args_w = data_w[:shape_cnt]
+ p = end_keys = shape_cnt + len(shape_keys)
+ if shape_star:
+ w_star = data_w[p]
+ p += 1
+ else:
+ w_star = None
+ if shape_stst:
+ w_starstar = data_w[p]
+ p += 1
+ else:
+ w_starstar = None
+ return ArgumentsForTranslation(space, args_w, list(shape_keys),
+ data_w[shape_cnt:end_keys], w_star,
+ w_starstar)
+
+ def flatten(self):
+ """ Argument <-> list of w_objects together with "shape" information """
+ shape_cnt, shape_keys, shape_star, shape_stst = self._rawshape()
+ data_w = self.arguments_w + [self.keywords_w[self.keywords.index(key)]
+ for key in shape_keys]
+ if shape_star:
+ data_w.append(self.w_stararg)
+ if shape_stst:
+ data_w.append(self.w_starstararg)
+ return (shape_cnt, shape_keys, shape_star, shape_stst), data_w
+
+ def _rawshape(self, nextra=0):
+ assert not self.combine_has_happened
+ shape_cnt = len(self.arguments_w)+nextra # Number of positional args
+ if self.keywords:
+ shape_keys = self.keywords[:] # List of keywords (strings)
+ shape_keys.sort()
+ else:
+ shape_keys = []
+ shape_star = self.w_stararg is not None # Flag: presence of *arg
+ shape_stst = self.w_starstararg is not None # Flag: presence of **kwds
+ return shape_cnt, tuple(shape_keys), shape_star, shape_stst # shape_keys are sorted
+
+def rawshape(args, nextra=0):
+ return args._rawshape(nextra)
+
+
+#
+# ArgErr family of exceptions raised in case of argument mismatch.
+# We try to give error messages following CPython's, which are very informative.
+#
+
+class ArgErr(Exception):
+
+ def getmsg(self):
+ raise NotImplementedError
+
+class ArgErrCount(ArgErr):
+
+ def __init__(self, got_nargs, nkwds, signature,
+ defaults_w, missing_args):
+ self.signature = signature
+
+ self.num_defaults = 0 if defaults_w is None else len(defaults_w)
+ self.missing_args = missing_args
+ self.num_args = got_nargs
+ self.num_kwds = nkwds
+
+ def getmsg(self):
+ n = self.signature.num_argnames()
+ if n == 0:
+ msg = "takes no arguments (%d given)" % (
+ self.num_args + self.num_kwds)
+ else:
+ defcount = self.num_defaults
+ has_kwarg = self.signature.has_kwarg()
+ num_args = self.num_args
+ num_kwds = self.num_kwds
+ if defcount == 0 and not self.signature.has_vararg():
+ msg1 = "exactly"
+ if not has_kwarg:
+ num_args += num_kwds
+ num_kwds = 0
+ elif not self.missing_args:
+ msg1 = "at most"
+ else:
+ msg1 = "at least"
+ has_kwarg = False
+ n -= defcount
+ if n == 1:
+ plural = ""
+ else:
+ plural = "s"
+ if has_kwarg or num_kwds > 0:
+ msg2 = " non-keyword"
+ else:
+ msg2 = ""
+ msg = "takes %s %d%s argument%s (%d given)" % (
+ msg1,
+ n,
+ msg2,
+ plural,
+ num_args)
+ return msg
+
+class ArgErrMultipleValues(ArgErr):
+
+ def __init__(self, argname):
+ self.argname = argname
+
+ def getmsg(self):
+ msg = "got multiple values for keyword argument '%s'" % (
+ self.argname)
+ return msg
+
+class ArgErrUnknownKwds(ArgErr):
+
+ def __init__(self, space, num_remainingkwds, keywords, kwds_mapping,
+ keyword_names_w):
+ name = ''
+ self.num_kwds = num_remainingkwds
+ if num_remainingkwds == 1:
+ for i in range(len(keywords)):
+ if i not in kwds_mapping:
+ name = keywords[i]
+ if name is None:
+ # We'll assume it's unicode. Encode it.
+ # Careful, I *think* it should not be possible to
+ # get an IndexError here but you never know.
+ try:
+ if keyword_names_w is None:
+ raise IndexError
+ # note: negative-based indexing from the end
+ w_name = keyword_names_w[i - len(keywords)]
+ except IndexError:
+ name = '?'
+ else:
+ w_enc = space.wrap(space.sys.defaultencoding)
+ w_err = space.wrap("replace")
+ w_name = space.call_method(w_name, "encode", w_enc,
+ w_err)
+ name = space.str_w(w_name)
+ break
+ self.kwd_name = name
+
+ def getmsg(self):
+ if self.num_kwds == 1:
+ msg = "got an unexpected keyword argument '%s'" % (
+ self.kwd_name)
+ else:
+ msg = "got %d unexpected keyword arguments" % (
+ self.num_kwds)
+ return msg
diff --git a/pypy/objspace/flow/bytecode.py b/pypy/objspace/flow/bytecode.py
--- a/pypy/objspace/flow/bytecode.py
+++ b/pypy/objspace/flow/bytecode.py
@@ -1,11 +1,30 @@
"""
Bytecode handling classes and functions for use by the flow space.
"""
-from pypy.interpreter.pycode import (BytecodeCorruption,
- cpython_code_signature)
from pypy.tool.stdlib_opcode import (host_bytecode_spec, EXTENDED_ARG,
HAVE_ARGUMENT)
-from pypy.interpreter.astcompiler.consts import CO_GENERATOR
+from pypy.objspace.flow.argument import Signature
+from pypy.objspace.flow.flowcontext import BytecodeCorruption
+
+CO_GENERATOR = 0x0020
+CO_VARARGS = 0x0004
+CO_VARKEYWORDS = 0x0008
+
+def cpython_code_signature(code):
+ "([list-of-arg-names], vararg-name-or-None, kwarg-name-or-None)."
+ argcount = code.co_argcount
+ argnames = list(code.co_varnames[:argcount])
+ if code.co_flags & CO_VARARGS:
+ varargname = code.co_varnames[argcount]
+ argcount += 1
+ else:
+ varargname = None
+ if code.co_flags & CO_VARKEYWORDS:
+ kwargname = code.co_varnames[argcount]
+ argcount += 1
+ else:
+ kwargname = None
+ return Signature(argnames, varargname, kwargname)
class HostCode(object):
"""
diff --git a/pypy/objspace/flow/flowcontext.py b/pypy/objspace/flow/flowcontext.py
--- a/pypy/objspace/flow/flowcontext.py
+++ b/pypy/objspace/flow/flowcontext.py
@@ -6,9 +6,8 @@
import collections
from pypy.tool.error import source_lines
-from pypy.interpreter import pyframe
-from pypy.interpreter.argument import ArgumentsForTranslation
-from pypy.interpreter.pyopcode import Return, BytecodeCorruption
+from pypy.tool.stdlib_opcode import host_bytecode_spec
+from pypy.objspace.flow.argument import ArgumentsForTranslation
from pypy.objspace.flow.model import (Constant, Variable, Block, Link,
UnwrapException, c_last_exception)
from pypy.objspace.flow.framestate import (FrameState, recursively_unflatten,
@@ -31,6 +30,10 @@
class StopFlowing(Exception):
pass
+class Return(Exception):
+ def __init__(self, value):
+ self.value = value
+
class FSException(Exception):
def __init__(self, w_type, w_value):
assert w_type is not None
@@ -46,6 +49,9 @@
class ImplicitOperationError(FSException):
pass
+class BytecodeCorruption(Exception):
+ pass
+
class SpamBlock(Block):
# make slots optional, for debugging
if hasattr(Block, '__slots__'):
@@ -206,6 +212,83 @@
# ____________________________________________________________
+_unary_ops = [('UNARY_POSITIVE', "pos"),
+ ('UNARY_NEGATIVE', "neg"),
+ ('UNARY_NOT', "not_"),
+ ('UNARY_CONVERT', "repr"),
+ ('UNARY_INVERT', "invert"),]
+
+def unaryoperation(OPCODE, op):
+ def UNARY_OP(self, *ignored):
+ operation = getattr(self.space, op)
+ w_1 = self.popvalue()
+ w_result = operation(w_1)
+ self.pushvalue(w_result)
+ UNARY_OP.unaryop = op
+ UNARY_OP.func_name = OPCODE
+ return UNARY_OP
+
+_binary_ops = [
+ ('BINARY_MULTIPLY', "mul"),
+ ('BINARY_TRUE_DIVIDE', "truediv"),
+ ('BINARY_FLOOR_DIVIDE', "floordiv"),
+ ('BINARY_DIVIDE', "div"),
+ ('BINARY_MODULO', "mod"),
+ ('BINARY_ADD', "add"),
+ ('BINARY_SUBTRACT', "sub"),
+ ('BINARY_SUBSCR', "getitem"),
+ ('BINARY_LSHIFT', "lshift"),
+ ('BINARY_RSHIFT', "rshift"),
+ ('BINARY_AND', "and_"),
+ ('BINARY_XOR', "xor"),
+ ('BINARY_OR', "or_"),
+ ('INPLACE_MULTIPLY', "inplace_mul"),
+ ('INPLACE_TRUE_DIVIDE', "inplace_truediv"),
+ ('INPLACE_FLOOR_DIVIDE', "inplace_floordiv"),
+ ('INPLACE_DIVIDE', "inplace_div"),
+ ('INPLACE_MODULO', "inplace_mod"),
+ ('INPLACE_ADD', "inplace_add"),
+ ('INPLACE_SUBTRACT', "inplace_sub"),
+ ('INPLACE_LSHIFT', "inplace_lshift"),
+ ('INPLACE_RSHIFT', "inplace_rshift"),
+ ('INPLACE_AND', "inplace_and"),
+ ('INPLACE_XOR', "inplace_xor"),
+ ('INPLACE_OR', "inplace_or"),
+]
+
+def binaryoperation(OPCODE, op):
+ """NOT_RPYTHON"""
+ def BINARY_OP(self, *ignored):
+ operation = getattr(self.space, op)
+ w_2 = self.popvalue()
+ w_1 = self.popvalue()
+ w_result = operation(w_1, w_2)
+ self.pushvalue(w_result)
+ BINARY_OP.binop = op
+ BINARY_OP.func_name = OPCODE
+ return BINARY_OP
+
+_unsupported_ops = [
+ ('BINARY_POWER', "a ** b"),
+ ('BUILD_CLASS', 'creating new classes'),
+ ('EXEC_STMT', 'exec statement'),
+ ('STOP_CODE', '???'),
+ ('STORE_NAME', 'modifying globals'),
+ ('INPLACE_POWER', 'a **= b'),
+ ('LOAD_LOCALS', 'locals()'),
+ ('IMPORT_STAR', 'import *'),
+ ('MISSING_OPCODE', '???'),
+ ('DELETE_GLOBAL', 'modifying globals'),
+ ('DELETE_NAME', 'modifying globals'),
+ ('DELETE_ATTR', 'deleting attributes'),
+]
+
+def unsupportedoperation(OPCODE, msg):
+ def UNSUPPORTED(self, *ignored):
+ raise FlowingError(self, "%s is not RPython" % (msg,))
+ UNSUPPORTED.func_name = OPCODE
+ return UNSUPPORTED
+
compare_method = [
"cmp_lt", # "<"
"cmp_le", # "<="
@@ -220,7 +303,8 @@
"cmp_exc_match",
]
-class FlowSpaceFrame(pyframe.CPythonFrame):
+class FlowSpaceFrame(object):
+ opcode_method_names = host_bytecode_spec.method_names
def __init__(self, space, graph, code):
self.graph = graph
@@ -228,7 +312,7 @@
self.pycode = code
self.space = space
self.w_globals = Constant(func.func_globals)
- self.lastblock = None
+ self.blockstack = []
self.init_closure(func.func_closure)
self.f_lineno = code.co_firstlineno
@@ -255,6 +339,63 @@
self.valuestackdepth = code.co_nlocals
self.locals_stack_w = [None] * (code.co_stacksize + code.co_nlocals)
+ def pushvalue(self, w_object):
+ depth = self.valuestackdepth
+ self.locals_stack_w[depth] = w_object
+ self.valuestackdepth = depth + 1
+
+ def popvalue(self):
+ depth = self.valuestackdepth - 1
+ assert depth >= self.pycode.co_nlocals, "pop from empty value stack"
+ w_object = self.locals_stack_w[depth]
+ self.locals_stack_w[depth] = None
+ self.valuestackdepth = depth
+ return w_object
+
+ def peekvalue(self, index_from_top=0):
+ # NOTE: top of the stack is peekvalue(0).
+ index = self.valuestackdepth + ~index_from_top
+ assert index >= self.pycode.co_nlocals, (
+ "peek past the bottom of the stack")
+ return self.locals_stack_w[index]
+
+ def pushrevvalues(self, n, values_w): # n should be len(values_w)
+ assert len(values_w) == n
+ for i in range(n - 1, -1, -1):
+ self.pushvalue(values_w[i])
+
+ def settopvalue(self, w_object, index_from_top=0):
+ index = self.valuestackdepth + ~index_from_top
+ assert index >= self.pycode.co_nlocals, (
+ "settop past the bottom of the stack")
+ self.locals_stack_w[index] = w_object
+
+ def popvalues(self, n):
+ values_w = [self.popvalue() for i in range(n)]
+ values_w.reverse()
+ return values_w
+
+ def peekvalues(self, n):
+ values_w = [None] * n
+ base = self.valuestackdepth - n
+ while True:
+ n -= 1
+ if n < 0:
+ break
+ values_w[n] = self.locals_stack_w[base+n]
+ return values_w
+
+ def dropvalues(self, n):
+ finaldepth = self.valuestackdepth - n
+ for n in range(finaldepth, self.valuestackdepth):
+ self.locals_stack_w[n] = None
+ self.valuestackdepth = finaldepth
+
+ def dropvaluesuntil(self, finaldepth):
+ for n in range(finaldepth, self.valuestackdepth):
+ self.locals_stack_w[n] = None
+ self.valuestackdepth = finaldepth
+
def save_locals_stack(self):
return self.locals_stack_w[:self.valuestackdepth]
@@ -262,6 +403,20 @@
self.locals_stack_w[:len(items_w)] = items_w
self.dropvaluesuntil(len(items_w))
+ def unrollstack(self, unroller_kind):
+ while self.blockstack:
+ block = self.blockstack.pop()
+ if (block.handling_mask & unroller_kind) != 0:
+ return block
+ block.cleanupstack(self)
+ return None
+
+ def unrollstack_and_jump(self, unroller):
+ block = self.unrollstack(unroller.kind)
+ if block is None:
+ raise BytecodeCorruption("misplaced bytecode - should not return")
+ return block.handle(self, unroller)
+
def getstate(self):
# getfastscope() can return real None, for undefined locals
data = self.save_locals_stack()
@@ -272,7 +427,7 @@
data.append(self.last_exception.w_type)
data.append(self.last_exception.w_value)
recursively_flatten(self.space, data)
- return FrameState(data, self.get_blocklist(), self.last_instr)
+ return FrameState(data, self.blockstack[:], self.last_instr)
def setstate(self, state):
""" Reset the frame to the given state. """
@@ -285,7 +440,7 @@
else:
self.last_exception = FSException(data[-2], data[-1])
self.last_instr = state.next_instr
- self.set_blocklist(state.blocklist)
+ self.blockstack = state.blocklist[:]
def recording(self, block):
""" Setup recording of the block and return the recorder. """
@@ -336,7 +491,6 @@
block = self.pendingblocks.popleft()
try:
self.recorder = self.recording(block)
- self.frame_finished_execution = False
while True:
self.last_instr = self.handle_bytecode(self.last_instr)
self.recorder.final_state = self.getstate()
@@ -362,9 +516,8 @@
except StopFlowing:
pass
- except Return:
- w_result = self.popvalue()
- assert w_result is not None
+ except Return as exc:
+ w_result = exc.value
link = Link([w_result], graph.returnblock)
self.recorder.crnt_block.closeblock(link)
@@ -540,8 +693,7 @@
w_returnvalue = self.popvalue()
block = self.unrollstack(SReturnValue.kind)
if block is None:
- self.pushvalue(w_returnvalue) # XXX ping pong
- raise Return
+ raise Return(w_returnvalue)
else:
unroller = SReturnValue(w_returnvalue)
next_instr = block.handle(self, unroller)
@@ -561,31 +713,25 @@
if w_top == self.space.w_None:
# finally: block with no unroller active
return
- try:
- unroller = self.space.unwrap(w_top)
- except UnwrapException:
- pass
+ elif isinstance(w_top, SuspendedUnroller):
+ # case of a finally: block
+ return self.unroll_finally(w_top)
else:
- if isinstance(unroller, SuspendedUnroller):
- # case of a finally: block
- return self.unroll_finally(unroller)
- # case of an except: block. We popped the exception type
- self.popvalue() # Now we pop the exception value
- unroller = self.space.unwrap(self.popvalue())
- return self.unroll_finally(unroller)
+ # case of an except: block. We popped the exception type
+ self.popvalue() # Now we pop the exception value
+ unroller = self.popvalue()
+ return self.unroll_finally(unroller)
def unroll_finally(self, unroller):
# go on unrolling the stack
block = self.unrollstack(unroller.kind)
if block is None:
- w_result = unroller.nomoreblocks()
- self.pushvalue(w_result)
- raise Return
+ unroller.nomoreblocks()
else:
return block.handle(self, unroller)
def POP_BLOCK(self, oparg, next_instr):
- block = self.pop_block()
+ block = self.blockstack.pop()
block.cleanupstack(self) # the block knows how to clean up the value stack
def JUMP_ABSOLUTE(self, jumpto, next_instr):
@@ -611,6 +757,41 @@
def PRINT_NEWLINE(self, oparg, next_instr):
self.space.appcall(rpython_print_newline)
+ def JUMP_FORWARD(self, jumpby, next_instr):
+ next_instr += jumpby
+ return next_instr
+
+ def POP_JUMP_IF_FALSE(self, target, next_instr):
+ w_value = self.popvalue()
+ if not self.space.is_true(w_value):
+ return target
+ return next_instr
+
+ def POP_JUMP_IF_TRUE(self, target, next_instr):
+ w_value = self.popvalue()
+ if self.space.is_true(w_value):
+ return target
+ return next_instr
+
+ def JUMP_IF_FALSE_OR_POP(self, target, next_instr):
+ w_value = self.peekvalue()
+ if not self.space.is_true(w_value):
+ return target
+ self.popvalue()
+ return next_instr
+
+ def JUMP_IF_TRUE_OR_POP(self, target, next_instr):
+ w_value = self.peekvalue()
+ if self.space.is_true(w_value):
+ return target
+ self.popvalue()
+ return next_instr
+
+ def GET_ITER(self, oparg, next_instr):
+ w_iterable = self.popvalue()
+ w_iterator = self.space.iter(w_iterable)
+ self.pushvalue(w_iterator)
+
def FOR_ITER(self, jumpby, next_instr):
w_iterator = self.peekvalue()
try:
@@ -626,16 +807,16 @@
return next_instr
def SETUP_LOOP(self, offsettoend, next_instr):
- block = LoopBlock(self, next_instr + offsettoend, self.lastblock)
- self.lastblock = block
+ block = LoopBlock(self, next_instr + offsettoend)
+ self.blockstack.append(block)
def SETUP_EXCEPT(self, offsettoend, next_instr):
- block = ExceptBlock(self, next_instr + offsettoend, self.lastblock)
- self.lastblock = block
+ block = ExceptBlock(self, next_instr + offsettoend)
+ self.blockstack.append(block)
def SETUP_FINALLY(self, offsettoend, next_instr):
- block = FinallyBlock(self, next_instr + offsettoend, self.lastblock)
- self.lastblock = block
+ block = FinallyBlock(self, next_instr + offsettoend)
+ self.blockstack.append(block)
def SETUP_WITH(self, offsettoend, next_instr):
# A simpler version than the 'real' 2.7 one:
@@ -645,8 +826,8 @@
w_exit = self.space.getattr(w_manager, self.space.wrap("__exit__"))
self.settopvalue(w_exit)
w_result = self.space.call_method(w_manager, "__enter__")
- block = WithBlock(self, next_instr + offsettoend, self.lastblock)
- self.lastblock = block
+ block = WithBlock(self, next_instr + offsettoend)
+ self.blockstack.append(block)
self.pushvalue(w_result)
def WITH_CLEANUP(self, oparg, next_instr):
@@ -654,14 +835,13 @@
# and cannot suppress the exception.
# This opcode changed a lot between CPython versions
if sys.version_info >= (2, 6):
- w_unroller = self.popvalue()
+ unroller = self.popvalue()
w_exitfunc = self.popvalue()
- self.pushvalue(w_unroller)
+ self.pushvalue(unroller)
else:
w_exitfunc = self.popvalue()
- w_unroller = self.peekvalue(0)
+ unroller = self.peekvalue(0)
- unroller = self.space.unwrap(w_unroller)
w_None = self.space.w_None
if isinstance(unroller, SApplicationException):
operr = unroller.operr
@@ -678,9 +858,14 @@
raise FlowingError(self, "Local variable referenced before assignment")
self.pushvalue(w_value)
+ def LOAD_CONST(self, constindex, next_instr):
+ w_const = self.getconstant_w(constindex)
+ self.pushvalue(w_const)
+
def LOAD_GLOBAL(self, nameindex, next_instr):
w_result = self.space.find_global(self.w_globals, self.getname_u(nameindex))
self.pushvalue(w_result)
+ LOAD_NAME = LOAD_GLOBAL
def LOAD_ATTR(self, nameindex, next_instr):
"obj.attributename"
@@ -693,6 +878,65 @@
def LOAD_DEREF(self, varindex, next_instr):
self.pushvalue(self.closure[varindex])
+ def STORE_FAST(self, varindex, next_instr):
+ w_newvalue = self.popvalue()
+ assert w_newvalue is not None
+ self.locals_stack_w[varindex] = w_newvalue
+
+ def STORE_GLOBAL(self, nameindex, next_instr):
+ varname = self.getname_u(nameindex)
+ raise FlowingError(self,
+ "Attempting to modify global variable %r." % (varname))
+
+ def POP_TOP(self, oparg, next_instr):
+ self.popvalue()
+
+ def ROT_TWO(self, oparg, next_instr):
+ w_1 = self.popvalue()
+ w_2 = self.popvalue()
+ self.pushvalue(w_1)
+ self.pushvalue(w_2)
+
+ def ROT_THREE(self, oparg, next_instr):
+ w_1 = self.popvalue()
+ w_2 = self.popvalue()
+ w_3 = self.popvalue()
+ self.pushvalue(w_1)
+ self.pushvalue(w_3)
+ self.pushvalue(w_2)
+
+ def ROT_FOUR(self, oparg, next_instr):
+ w_1 = self.popvalue()
+ w_2 = self.popvalue()
+ w_3 = self.popvalue()
+ w_4 = self.popvalue()
+ self.pushvalue(w_1)
+ self.pushvalue(w_4)
+ self.pushvalue(w_3)
+ self.pushvalue(w_2)
+
+ def DUP_TOP(self, oparg, next_instr):
+ w_1 = self.peekvalue()
+ self.pushvalue(w_1)
+
+ def DUP_TOPX(self, itemcount, next_instr):
+ delta = itemcount - 1
+ while True:
+ itemcount -= 1
+ if itemcount < 0:
+ break
+ w_value = self.peekvalue(delta)
+ self.pushvalue(w_value)
+
+ for OPCODE, op in _unary_ops:
+ locals()[OPCODE] = unaryoperation(OPCODE, op)
+
+ for OPCODE, op in _binary_ops:
+ locals()[OPCODE] = binaryoperation(OPCODE, op)
+
+ for OPCODE, op in _unsupported_ops:
+ locals()[OPCODE] = unsupportedoperation(OPCODE, op)
+
def BUILD_LIST_FROM_ARG(self, _, next_instr):
# This opcode was added with pypy-1.8. Here is a simpler
# version, enough for annotation.
@@ -700,12 +944,188 @@
self.pushvalue(self.space.newlist([]))
self.pushvalue(last_val)
+ def call_function(self, oparg, w_star=None, w_starstar=None):
+ n_arguments = oparg & 0xff
+ n_keywords = (oparg>>8) & 0xff
+ if n_keywords:
+ keywords = [None] * n_keywords
+ keywords_w = [None] * n_keywords
+ while True:
+ n_keywords -= 1
+ if n_keywords < 0:
+ break
+ w_value = self.popvalue()
+ w_key = self.popvalue()
+ key = self.space.str_w(w_key)
+ keywords[n_keywords] = key
+ keywords_w[n_keywords] = w_value
+ else:
+ keywords = None
+ keywords_w = None
+ arguments = self.popvalues(n_arguments)
+ args = self.argument_factory(arguments, keywords, keywords_w, w_star,
+ w_starstar)
+ w_function = self.popvalue()
+ w_result = self.space.call_args(w_function, args)
+ self.pushvalue(w_result)
+
+ def CALL_FUNCTION(self, oparg, next_instr):
+ self.call_function(oparg)
+ CALL_METHOD = CALL_FUNCTION
+
+ def CALL_FUNCTION_VAR(self, oparg, next_instr):
+ w_varargs = self.popvalue()
+ self.call_function(oparg, w_varargs)
+
+ def CALL_FUNCTION_KW(self, oparg, next_instr):
+ w_varkw = self.popvalue()
+ self.call_function(oparg, None, w_varkw)
+
+ def CALL_FUNCTION_VAR_KW(self, oparg, next_instr):
+ w_varkw = self.popvalue()
+ w_varargs = self.popvalue()
+ self.call_function(oparg, w_varargs, w_varkw)
+
def MAKE_FUNCTION(self, numdefaults, next_instr):
w_codeobj = self.popvalue()
defaults = self.popvalues(numdefaults)
fn = self.space.newfunction(w_codeobj, self.w_globals, defaults)
self.pushvalue(fn)
+ def STORE_ATTR(self, nameindex, next_instr):
+ "obj.attributename = newvalue"
+ w_attributename = self.getname_w(nameindex)
+ w_obj = self.popvalue()
+ w_newvalue = self.popvalue()
+ self.space.setattr(w_obj, w_attributename, w_newvalue)
+
+ def UNPACK_SEQUENCE(self, itemcount, next_instr):
+ w_iterable = self.popvalue()
+ items = self.space.unpackiterable(w_iterable, itemcount)
+ self.pushrevvalues(itemcount, items)
+
+ def slice(self, w_start, w_end):
+ w_obj = self.popvalue()
+ w_result = self.space.getslice(w_obj, w_start, w_end)
+ self.pushvalue(w_result)
+
+ def SLICE_0(self, oparg, next_instr):
+ self.slice(self.space.w_None, self.space.w_None)
+
+ def SLICE_1(self, oparg, next_instr):
+ w_start = self.popvalue()
+ self.slice(w_start, self.space.w_None)
+
+ def SLICE_2(self, oparg, next_instr):
+ w_end = self.popvalue()
+ self.slice(self.space.w_None, w_end)
+
+ def SLICE_3(self, oparg, next_instr):
+ w_end = self.popvalue()
+ w_start = self.popvalue()
+ self.slice(w_start, w_end)
+
+ def storeslice(self, w_start, w_end):
+ w_obj = self.popvalue()
+ w_newvalue = self.popvalue()
+ self.space.setslice(w_obj, w_start, w_end, w_newvalue)
+
+ def STORE_SLICE_0(self, oparg, next_instr):
+ self.storeslice(self.space.w_None, self.space.w_None)
+
+ def STORE_SLICE_1(self, oparg, next_instr):
+ w_start = self.popvalue()
+ self.storeslice(w_start, self.space.w_None)
+
+ def STORE_SLICE_2(self, oparg, next_instr):
+ w_end = self.popvalue()
+ self.storeslice(self.space.w_None, w_end)
+
+ def STORE_SLICE_3(self, oparg, next_instr):
+ w_end = self.popvalue()
+ w_start = self.popvalue()
+ self.storeslice(w_start, w_end)
+
+ def deleteslice(self, w_start, w_end):
+ w_obj = self.popvalue()
+ self.space.delslice(w_obj, w_start, w_end)
+
+ def DELETE_SLICE_0(self, oparg, next_instr):
+ self.deleteslice(self.space.w_None, self.space.w_None)
+
+ def DELETE_SLICE_1(self, oparg, next_instr):
+ w_start = self.popvalue()
+ self.deleteslice(w_start, self.space.w_None)
+
+ def DELETE_SLICE_2(self, oparg, next_instr):
+ w_end = self.popvalue()
+ self.deleteslice(self.space.w_None, w_end)
+
+ def DELETE_SLICE_3(self, oparg, next_instr):
+ w_end = self.popvalue()
+ w_start = self.popvalue()
+ self.deleteslice(w_start, w_end)
+
+ def LIST_APPEND(self, oparg, next_instr):
+ w = self.popvalue()
+ v = self.peekvalue(oparg - 1)
+ self.space.call_method(v, 'append', w)
+
+ def DELETE_FAST(self, varindex, next_instr):
+ if self.locals_stack_w[varindex] is None:
+ varname = self.getlocalvarname(varindex)
+ message = "local variable '%s' referenced before assignment"
+ raise UnboundLocalError(message, varname)
+ self.locals_stack_w[varindex] = None
+
+ def STORE_MAP(self, oparg, next_instr):
+ w_key = self.popvalue()
+ w_value = self.popvalue()
+ w_dict = self.peekvalue()
+ self.space.setitem(w_dict, w_key, w_value)
+
+ def STORE_SUBSCR(self, oparg, next_instr):
+ "obj[subscr] = newvalue"
+ w_subscr = self.popvalue()
+ w_obj = self.popvalue()
+ w_newvalue = self.popvalue()
+ self.space.setitem(w_obj, w_subscr, w_newvalue)
+
+ def BUILD_SLICE(self, numargs, next_instr):
+ if numargs == 3:
+ w_step = self.popvalue()
+ elif numargs == 2:
+ w_step = self.space.w_None
+ else:
+ raise BytecodeCorruption
+ w_end = self.popvalue()
+ w_start = self.popvalue()
+ w_slice = self.space.newslice(w_start, w_end, w_step)
+ self.pushvalue(w_slice)
+
+ def DELETE_SUBSCR(self, oparg, next_instr):
+ "del obj[subscr]"
+ w_subscr = self.popvalue()
+ w_obj = self.popvalue()
+ self.space.delitem(w_obj, w_subscr)
+
+ def BUILD_TUPLE(self, itemcount, next_instr):
+ items = self.popvalues(itemcount)
+ w_tuple = self.space.newtuple(items)
+ self.pushvalue(w_tuple)
+
+ def BUILD_LIST(self, itemcount, next_instr):
+ items = self.popvalues(itemcount)
+ w_list = self.space.newlist(items)
+ self.pushvalue(w_list)
+
+ def BUILD_MAP(self, itemcount, next_instr):
+ w_dict = self.space.newdict()
+ self.pushvalue(w_dict)
+
+ def NOP(self, *args):
+ pass
+
# XXX Unimplemented 2.7 opcodes ----------------
# Set literals, set comprehensions
@@ -765,7 +1185,7 @@
self.w_returnvalue = w_returnvalue
def nomoreblocks(self):
- return self.w_returnvalue
+ raise Return(self.w_returnvalue)
def state_unpack_variables(self, space):
return [self.w_returnvalue]
@@ -823,10 +1243,9 @@
"""Abstract base class for frame blocks from the blockstack,
used by the SETUP_XXX and POP_BLOCK opcodes."""
- def __init__(self, frame, handlerposition, previous):
+ def __init__(self, frame, handlerposition):
self.handlerposition = handlerposition
self.valuestackdepth = frame.valuestackdepth
- self.previous = previous # this makes a linked list of blocks
def __eq__(self, other):
return (self.__class__ is other.__class__ and
@@ -856,7 +1275,7 @@
# re-push the loop block without cleaning up the value stack,
# and jump to the beginning of the loop, stored in the
# exception's argument
- frame.append_block(self)
+ frame.blockstack.append(self)
return unroller.jump_to
else:
# jump to the end of the loop
@@ -878,7 +1297,7 @@
# the stack setup is slightly different than in CPython:
# instead of the traceback, we store the unroller object,
# wrapped.
- frame.pushvalue(frame.space.wrap(unroller))
+ frame.pushvalue(unroller)
frame.pushvalue(operationerr.get_w_value(frame.space))
frame.pushvalue(operationerr.w_type)
frame.last_exception = operationerr
@@ -894,7 +1313,7 @@
# any abnormal reason for unrolling a finally: triggers the end of
# the block unrolling and the entering the finally: handler.
self.cleanupstack(frame)
- frame.pushvalue(frame.space.wrap(unroller))
+ frame.pushvalue(unroller)
return self.handlerposition # jump to the handler
diff --git a/pypy/objspace/flow/framestate.py b/pypy/objspace/flow/framestate.py
--- a/pypy/objspace/flow/framestate.py
+++ b/pypy/objspace/flow/framestate.py
@@ -6,9 +6,6 @@
self.mergeable = mergeable
self.blocklist = blocklist
self.next_instr = next_instr
- for w1 in self.mergeable:
- assert isinstance(w1, (Variable, Constant)) or w1 is None, (
- '%r found in frame state' % w1)
def copy(self):
"Make a copy of this state in which all Variables are fresh."
@@ -109,12 +106,10 @@
from pypy.objspace.flow.flowcontext import SuspendedUnroller
i = 0
while i < len(lst):
- item = lst[i]
- if not (isinstance(item, Constant) and
- isinstance(item.value, SuspendedUnroller)):
+ unroller = lst[i]
+ if not isinstance(unroller, SuspendedUnroller):
i += 1
else:
- unroller = item.value
vars = unroller.state_unpack_variables(space)
key = unroller.__class__, len(vars)
try:
@@ -132,4 +127,4 @@
arguments = lst[i+1: i+1+argcount]
del lst[i+1: i+1+argcount]
unroller = unrollerclass.state_pack_variables(space, *arguments)
- lst[i] = space.wrap(unroller)
+ lst[i] = unroller
diff --git a/pypy/objspace/flow/generator.py b/pypy/objspace/flow/generator.py
--- a/pypy/objspace/flow/generator.py
+++ b/pypy/objspace/flow/generator.py
@@ -6,7 +6,7 @@
from pypy.translator.unsimplify import split_block
from pypy.translator.simplify import eliminate_empty_blocks, simplify_graph
from pypy.tool.sourcetools import func_with_new_name
-from pypy.interpreter.argument import Signature
+from pypy.objspace.flow.argument import Signature
class AbstractPosition(object):
diff --git a/pypy/objspace/flow/objspace.py b/pypy/objspace/flow/objspace.py
--- a/pypy/objspace/flow/objspace.py
+++ b/pypy/objspace/flow/objspace.py
@@ -7,8 +7,7 @@
import types
from inspect import CO_NEWLOCALS
-from pypy.interpreter.baseobjspace import ObjSpace
-from pypy.interpreter.argument import ArgumentsForTranslation
+from pypy.objspace.flow.argument import ArgumentsForTranslation
from pypy.objspace.flow.model import (Constant, Variable, WrapException,
UnwrapException, checkgraph, SpaceOperation)
from pypy.objspace.flow.bytecode import HostCode
@@ -226,7 +225,7 @@
w_real_class = self.wrap(rstackovf._StackOverflow)
return self._exception_match(w_exc_type, w_real_class)
# checking a tuple of classes
- for w_klass in self.fixedview(w_check_class):
+ for w_klass in self.unpackiterable(w_check_class):
if self.exception_match(w_exc_type, w_klass):
return True
return False
@@ -285,10 +284,6 @@
tweak_generator_graph(graph)
return graph
- def fixedview(self, w_tuple, expected_length=None):
- return self.unpackiterable(w_tuple, expected_length)
- listview = fixedview_unroll = fixedview
-
def unpackiterable(self, w_iterable, expected_length=None):
if not isinstance(w_iterable, Variable):
l = list(self.unwrap(w_iterable))
@@ -427,10 +422,6 @@
raise FSException(self.w_ImportError,
self.wrap("cannot import name '%s'" % w_name.value))
- def call_valuestack(self, w_func, nargs, frame):
- args = frame.make_arguments(nargs)
- return self.call_args(w_func, args)
-
def call_method(self, w_obj, methname, *arg_w):
w_meth = self.getattr(w_obj, self.wrap(methname))
return self.call_function(w_meth, *arg_w)
@@ -577,5 +568,5 @@
setattr(FlowObjSpace, name, generic_operator)
-for (name, symbol, arity, specialnames) in ObjSpace.MethodTable:
+for (name, symbol, arity, specialnames) in operation.MethodTable:
More information about the pypy-commit
mailing list