[pypy-commit] pypy cffi-handle-lifetime: add the interface 'instantiate(Cls, nonmovable=True)'
arigo
noreply at buildbot.pypy.org
Sun Oct 11 19:29:33 CEST 2015
Author: Armin Rigo <arigo at tunes.org>
Branch: cffi-handle-lifetime
Changeset: r80111:57dfab5e28fa
Date: 2015-10-11 19:04 +0200
http://bitbucket.org/pypy/pypy/changeset/57dfab5e28fa/
Log: add the interface 'instantiate(Cls, nonmovable=True)'
diff --git a/rpython/annotator/builtin.py b/rpython/annotator/builtin.py
--- a/rpython/annotator/builtin.py
+++ b/rpython/annotator/builtin.py
@@ -290,7 +290,7 @@
return SomeInteger(knowntype=rpython.rlib.rarithmetic.r_longlong)
@analyzer_for(rpython.rlib.objectmodel.instantiate)
-def robjmodel_instantiate(s_clspbc):
+def robjmodel_instantiate(s_clspbc, s_nonmovable=None):
assert isinstance(s_clspbc, SomePBC)
clsdef = None
more_than_one = len(s_clspbc.descriptions) > 1
diff --git a/rpython/rlib/objectmodel.py b/rpython/rlib/objectmodel.py
--- a/rpython/rlib/objectmodel.py
+++ b/rpython/rlib/objectmodel.py
@@ -276,7 +276,7 @@
# ____________________________________________________________
-def instantiate(cls):
+def instantiate(cls, nonmovable=False):
"Create an empty instance of 'cls'."
if isinstance(cls, type):
return cls.__new__(cls)
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -693,18 +693,24 @@
return hop.args_r[0].rtype_isinstance(hop)
@typer_for(objectmodel.instantiate)
-def rtype_instantiate(hop):
+def rtype_instantiate(hop, i_nonmovable=None):
hop.exception_cannot_occur()
s_class = hop.args_s[0]
assert isinstance(s_class, annmodel.SomePBC)
+ v_nonmovable, = parse_kwds(hop, (i_nonmovable, None))
+ nonmovable = (i_nonmovable is not None and v_nonmovable.value)
if len(s_class.descriptions) != 1:
# instantiate() on a variable class
+ if nonmovable:
+ raise TyperError("instantiate(x, nonmovable=True) cannot be used "
+ "if x is not a constant class")
vtypeptr, = hop.inputargs(rclass.get_type_repr(hop.rtyper))
r_class = hop.args_r[0]
return r_class._instantiate_runtime_class(hop, vtypeptr,
hop.r_result.lowleveltype)
classdef = s_class.any_description().getuniqueclassdef()
- return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops)
+ return rclass.rtype_new_instance(hop.rtyper, classdef, hop.llops,
+ nonmovable=nonmovable)
@typer_for(hasattr)
diff --git a/rpython/rtyper/rclass.py b/rpython/rtyper/rclass.py
--- a/rpython/rtyper/rclass.py
+++ b/rpython/rtyper/rclass.py
@@ -684,10 +684,12 @@
rbase = rbase.rbase
return False
- def new_instance(self, llops, classcallhop=None):
+ def new_instance(self, llops, classcallhop=None, nonmovable=False):
"""Build a new instance, without calling __init__."""
flavor = self.gcflavor
flags = {'flavor': flavor}
+ if nonmovable:
+ flags['nonmovable'] = True
ctype = inputconst(Void, self.object_type)
cflags = inputconst(Void, flags)
vlist = [ctype, cflags]
@@ -1031,9 +1033,10 @@
# ____________________________________________________________
-def rtype_new_instance(rtyper, classdef, llops, classcallhop=None):
+def rtype_new_instance(rtyper, classdef, llops, classcallhop=None,
+ nonmovable=False):
rinstance = getinstancerepr(rtyper, classdef)
- return rinstance.new_instance(llops, classcallhop)
+ return rinstance.new_instance(llops, classcallhop, nonmovable=nonmovable)
def ll_inst_hash(ins):
if not ins:
diff --git a/rpython/rtyper/test/test_rbuiltin.py b/rpython/rtyper/test/test_rbuiltin.py
--- a/rpython/rtyper/test/test_rbuiltin.py
+++ b/rpython/rtyper/test/test_rbuiltin.py
@@ -432,6 +432,14 @@
res = self.interpret(f, [2])
assert self.class_name(res) == 'B'
+ def test_instantiate_nonmovable(self):
+ class A:
+ pass
+ def f():
+ return instantiate(A, nonmovable=True) # no effect before GC
+ res = self.interpret(f, [])
+ assert self.class_name(res) == 'A'
+
def test_os_path_join(self):
def fn(a, b):
return os.path.join(a, b)
More information about the pypy-commit
mailing list