From fijal at codespeak.net Mon Jan 1 11:51:11 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 11:51:11 +0100 (CET)
Subject: [pypy-svn] r36084 - pypy/dist/pypy/doc/js
Message-ID: <20070101105111.6C6351007E@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 11:51:09 2007
New Revision: 36084
Modified:
pypy/dist/pypy/doc/js/webapps_with_pypy.txt
Log:
* Added important sentence (what is rpython)
* Reworded CPython/Python
Modified: pypy/dist/pypy/doc/js/webapps_with_pypy.txt
==============================================================================
--- pypy/dist/pypy/doc/js/webapps_with_pypy.txt (original)
+++ pypy/dist/pypy/doc/js/webapps_with_pypy.txt Mon Jan 1 11:51:09 2007
@@ -26,7 +26,9 @@
JavaScript code. Unlike other libraries that perform similar functionality,
PyPy really interprets the code, and produces 'lower level' JavaScript code,
so it implements Python core language features like list comprehensions, and
-really behaves like Python (it's not Python syntax with JS semantics).
+really behaves like Python (it's not Python syntax with JS semantics).
+This particulary means that when a program is in RPython, you can run it
+on top of Python interpreter with the same results as translated to JS version.
However, mostly for demonstration purposes, some other interesting code is
available in the PyPy code package that may help developing web apps. The most
@@ -52,7 +54,7 @@
A quick overview of the (main) layers of code in the application we're going
to write:
- * HTTP server implementation - 'normal' (C-)Python code
+ * HTTP server implementation - 'normal' Python code
the web server code, the code that handles dealing with the HTTP API and
dispatching to application code is written in 'normal' Python code, and is
From fijal at codespeak.net Mon Jan 1 11:55:42 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 11:55:42 +0100 (CET)
Subject: [pypy-svn] r36085 - pypy/dist/pypy/doc/js
Message-ID: <20070101105542.73B061007E@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 11:55:40 2007
New Revision: 36085
Modified:
pypy/dist/pypy/doc/js/webapps_with_pypy.txt
Log:
Added link.
Modified: pypy/dist/pypy/doc/js/webapps_with_pypy.txt
==============================================================================
--- pypy/dist/pypy/doc/js/webapps_with_pypy.txt (original)
+++ pypy/dist/pypy/doc/js/webapps_with_pypy.txt Mon Jan 1 11:55:40 2007
@@ -7,7 +7,7 @@
PyPy is a platform that is very versatile, and provides almost endless
possibilities. One of the features that is currently already available is
-that of translating RPython (the 'restricted Python' subset) to JavaScript.
+that of translating `RPython`_ (the 'restricted Python' subset) to JavaScript.
This specific feature can make the life of a developer of web applications that
use client-side logic a lot easier, although there are certain hurdles to take.
@@ -89,3 +89,4 @@
XXX hands-on guide to writing guestbook or something
+.. _`RPython`: ../coding-guide.html#restricted-python
\ No newline at end of file
From fijal at codespeak.net Mon Jan 1 11:58:26 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 11:58:26 +0100 (CET)
Subject: [pypy-svn] r36086 - pypy/dist/pypy/lib/distributed/test
Message-ID: <20070101105826.190B21007E@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 11:58:24 2007
New Revision: 36086
Added:
pypy/dist/pypy/lib/distributed/test/
Log:
Added test directory
From fijal at codespeak.net Mon Jan 1 11:59:04 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 11:59:04 +0100 (CET)
Subject: [pypy-svn] r36087 - in pypy/dist/pypy/lib: distributed/test test2
Message-ID: <20070101105904.D5C7A1007E@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 11:59:03 2007
New Revision: 36087
Added:
pypy/dist/pypy/lib/distributed/test/test_distributed.py
- copied unchanged from r36076, pypy/dist/pypy/lib/test2/test_distributed.py
Removed:
pypy/dist/pypy/lib/test2/test_distributed.py
Log:
Moved tests from deprecated directory
From fijal at codespeak.net Mon Jan 1 12:51:53 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 12:51:53 +0100 (CET)
Subject: [pypy-svn] r36088 - in pypy/dist/pypy/translator/js/modules: . test
Message-ID: <20070101115153.825511007F@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 12:51:51 2007
New Revision: 36088
Removed:
pypy/dist/pypy/translator/js/modules/bltns.py
pypy/dist/pypy/translator/js/modules/test/test_xmlhttp.py
pypy/dist/pypy/translator/js/modules/xmlhttp.py
Log:
Removed deprecated files.
From fijal at codespeak.net Mon Jan 1 14:52:58 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 14:52:58 +0100 (CET)
Subject: [pypy-svn] r36091 - pypy/dist/pypy/translator/js/doc
Message-ID: <20070101135258.E2ECA1007F@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 14:52:57 2007
New Revision: 36091
Removed:
pypy/dist/pypy/translator/js/doc/
Log:
Removed unused dir.
From fijal at codespeak.net Mon Jan 1 15:27:58 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 15:27:58 +0100 (CET)
Subject: [pypy-svn] r36092 - in pypy/dist/pypy/translator/js/examples: . test
Message-ID: <20070101142758.AF94A1007F@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 15:27:57 2007
New Revision: 36092
Modified:
pypy/dist/pypy/translator/js/examples/server.py
pypy/dist/pypy/translator/js/examples/test/test_server.py
Log:
Add a test and not fork by default.
Modified: pypy/dist/pypy/translator/js/examples/server.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/server.py (original)
+++ pypy/dist/pypy/translator/js/examples/server.py Mon Jan 1 15:27:57 2007
@@ -98,10 +98,10 @@
self.end_headers()
self.wfile.write(data)
-def start_server(server_address = ('', 8000), handler=TestHandler, start_new=True):
+def start_server(server_address = ('', 8000), handler=TestHandler, fork=False):
httpd = HTTPServer(server_address, handler)
- if start_new:
+ if fork:
import thread
thread.start_new_thread(httpd.serve_forever, ())
print "Server started, listening on %s" % (server_address,)
Modified: pypy/dist/pypy/translator/js/examples/test/test_server.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/test/test_server.py (original)
+++ pypy/dist/pypy/translator/js/examples/test/test_server.py Mon Jan 1 15:27:57 2007
@@ -17,3 +17,7 @@
thread.start_new_thread(httpd.serve_forever, ())
assert URLopener().open("http://127.0.0.1:21210/index").read() == "xxx"
+def test_own_startup():
+ server.start_server(server_address=('127.0.0.1', 21211),
+ handler=Handler, fork=True)
+ assert URLopener().open("http://127.0.0.1:21210/index").read() == "xxx"
From fijal at codespeak.net Mon Jan 1 15:44:33 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 15:44:33 +0100 (CET)
Subject: [pypy-svn] r36094 - in pypy/dist/pypy/translator/js: . test
Message-ID: <20070101144433.0D5501007F@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 15:44:31 2007
New Revision: 36094
Modified:
pypy/dist/pypy/translator/js/main.py
pypy/dist/pypy/translator/js/test/test_main.py
Log:
Added possibility not to specify module (caller module) and a test.
Modified: pypy/dist/pypy/translator/js/main.py
==============================================================================
--- pypy/dist/pypy/translator/js/main.py (original)
+++ pypy/dist/pypy/translator/js/main.py Mon Jan 1 15:44:31 2007
@@ -113,6 +113,15 @@
return retval
def rpython2javascript(mod, function_names, jsconfig=None, use_pdb=True):
+ if isinstance(function_names, str):
+ function_names = [function_names]
+ # avoid confusion
+ if mod is None:
+ # this means actual module, which is quite hairy to get in python,
+ # so we cheat
+ import sys
+ mod = sys.modules[sys._getframe(1).f_globals['__name__']]
+
if jsconfig is None:
jsconfig = Config(js_optiondescr)
if use_pdb:
Modified: pypy/dist/pypy/translator/js/test/test_main.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_main.py (original)
+++ pypy/dist/pypy/translator/js/test/test_main.py Mon Jan 1 15:44:31 2007
@@ -21,6 +21,12 @@
def fun(x='3'):
return a.method({'a':x})['a']
+def fff():
+ pass
+
def test_bookkeeper_cleanup():
- rpython2javascript(sys.modules[__name__], ["fun"])
- rpython2javascript(sys.modules[__name__], ["fun"])
+ assert rpython2javascript(sys.modules[__name__], ["fun"])
+ assert rpython2javascript(sys.modules[__name__], ["fun"])
+
+def test_module_none():
+ assert rpython2javascript(None, "fff")
From fijal at codespeak.net Mon Jan 1 15:50:34 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 15:50:34 +0100 (CET)
Subject: [pypy-svn] r36095 - pypy/dist/pypy/translator/js/modules
Message-ID: <20070101145034.E9BAA1007F@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 15:50:33 2007
New Revision: 36095
Added:
pypy/dist/pypy/translator/js/modules/browser.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/js/modules/dom.py
Log:
Moved some stuff (one function for now) from dom to browser.
Added: pypy/dist/pypy/translator/js/modules/browser.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/modules/browser.py Mon Jan 1 15:50:33 2007
@@ -0,0 +1,9 @@
+
+"""
+Here are some functions which does not belong to dom, but rather
+to browser itself
+"""
+
+def alert(msg):
+ pass
+alert.suggested_primitive = True
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Mon Jan 1 15:50:33 2007
@@ -303,9 +303,6 @@
func()
#pass
-def alert(msg):
- pass
-
# some helper functions (XXX imo these can go, but the code seems to use them
# a lot... isn't it possible to just use dom.window and dom.document instead?)
From fijal at codespeak.net Mon Jan 1 15:55:51 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 15:55:51 +0100 (CET)
Subject: [pypy-svn] r36096 - pypy/dist/pypy/translator/js/modules
Message-ID: <20070101145551.57DC01007F@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 15:55:50 2007
New Revision: 36096
Modified:
pypy/dist/pypy/translator/js/modules/dom.py
Log:
oops.
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Mon Jan 1 15:55:50 2007
@@ -694,7 +694,6 @@
get_window.suggested_primitive = True
get_document.suggested_primitive = True
setTimeout.suggested_primitive = True
-alert.suggested_primitive = True
# the following code wraps minidom nodes with Node classes, and makes
# sure all methods on the nodes return wrapped nodes
From fijal at codespeak.net Mon Jan 1 16:06:35 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 16:06:35 +0100 (CET)
Subject: [pypy-svn] r36097 - pypy/dist/pypy/translator/js/tutorial
Message-ID: <20070101150635.DF72E1007A@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 16:06:34 2007
New Revision: 36097
Added:
pypy/dist/pypy/translator/js/tutorial/
pypy/dist/pypy/translator/js/tutorial/__init__.py (contents, props changed)
pypy/dist/pypy/translator/js/tutorial/step1.py (contents, props changed)
pypy/dist/pypy/translator/js/tutorial/step2.py (contents, props changed)
Log:
Added two simple steps how to start, this is intermediate checkin.
Added: pypy/dist/pypy/translator/js/tutorial/__init__.py
==============================================================================
Added: pypy/dist/pypy/translator/js/tutorial/step1.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/tutorial/step1.py Mon Jan 1 16:06:34 2007
@@ -0,0 +1,27 @@
+#!/usr/bin/env python
+"""
+
+This is simple all-in-one self-containing server,
+which just shows almost-empty HTML page
+
+"""
+
+# here we import server, which is derivative of
+# BaseHTTPServer from python standard library
+from pypy.translator.js.examples import server
+
+# We create handler, which will handle all our requests
+class Handler(server.TestHandler):
+
+ def index(self):
+ # provide some html contents
+ return "
Something
"
+ # this line is necessary to make server show something,
+ # otherwise method is considered private-only
+ index.exposed = True
+
+if __name__ == '__main__':
+ # let's start our server,
+ # this will create running server instance on port 8000 by default,
+ # which will run until we press Control-C
+ server.start_server(handler=Handler)
Added: pypy/dist/pypy/translator/js/tutorial/step2.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/tutorial/step2.py Mon Jan 1 16:06:34 2007
@@ -0,0 +1,52 @@
+#!/usr/bin/env python
+"""
+In this example, we'll show how to add javascript to our simple
+server from previous example
+"""
+
+from pypy.translator.js.examples import server
+import sys
+
+# here we have virtual script "source.js" which we generate
+# on-the-fly when requested
+HTML = """
+
+
+
+ pypy.js tutorial
+
+
+
+
+"""
+
+from pypy.translator.js.main import rpython2javascript
+# here we import rpython -> javascript conversion utility
+
+from pypy.translator.js.modules import browser
+# and here we import functions from modules that we want to use
+
+# this is function which will be translated into javascript,
+# we can put it in a different module if we like so
+def show():
+ browser.alert("Alert")
+
+class Handler(server.TestHandler):
+
+ def index(self):
+ return HTML
+ index.exposed = True
+
+ # here we generate javascript, this will be accessed when
+ # asked for source.js
+ def source_js(self):
+ # this returns content-type (if not text/html)
+ # and generated javascript code
+ # None as argument means current module, while "show" is the
+ # name of function to be exported (under same name)
+ return "text/javascript", rpython2javascript(None, ["show"])
+ source_js.exposed = True
+
+# server start, same as before
+if __name__ == '__main__':
+ server.start_server(handler=Handler)
From fijal at codespeak.net Mon Jan 1 19:07:38 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Mon, 1 Jan 2007 19:07:38 +0100 (CET)
Subject: [pypy-svn] r36098 - pypy/dist/pypy/translator/js/tutorial
Message-ID: <20070101180738.3C29210078@code0.codespeak.net>
Author: fijal
Date: Mon Jan 1 19:07:36 2007
New Revision: 36098
Added:
pypy/dist/pypy/translator/js/tutorial/step3.py (contents, props changed)
Log:
Added another tutorial-like example.
Added: pypy/dist/pypy/translator/js/tutorial/step3.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/tutorial/step3.py Mon Jan 1 19:07:36 2007
@@ -0,0 +1,62 @@
+#!/usr/bin/env python
+"""
+In this example I'll show how to manipulate DOM tree
+from inside RPython code
+
+Note that this is low-level API to manipulate it, which
+might be suitable if you don't like boilerplate on top.
+
+There is ongoing effort to provide API of somewhat higher level,
+which will be way easier to manipulate.
+"""
+
+from pypy.translator.js.examples import server
+from pypy.translator.js.main import rpython2javascript
+from pypy.translator.js.modules import dom
+# dom manipulating module
+
+HTML = """
+
+
+
+ pypy.js tutorial
+
+
+
+Add row
+Del row
+
+
+"""
+
+# these are exposed functions
+def addrow():
+ doc = dom.get_document()
+
+ # we need to call a helper, similiar to document in JS
+ tr = doc.createElement("tr")
+ td = doc.createElement("td")
+ td.appendChild(doc.createTextNode("A row"))
+ tr.appendChild(td)
+ dom.get_document().getElementById("atable").appendChild(tr)
+
+def delrow():
+ table = dom.get_document().getElementById("atable")
+ # note -1 working here like in python, this is last element in list
+ table.removeChild(table.childNodes[-1])
+
+class Handler(server.TestHandler):
+
+ def index(self):
+ return HTML
+ index.exposed = True
+
+ def source_js(self):
+ return "text/javascript", rpython2javascript(None, ["addrow", "delrow"])
+ source_js.exposed = True
+
+# server start, same as before
+if __name__ == '__main__':
+ server.start_server(handler=Handler)
From fijal at codespeak.net Tue Jan 2 00:20:45 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 00:20:45 +0100 (CET)
Subject: [pypy-svn] r36100 - in pypy/dist/pypy/translator/js: . demo/jsdemo
test
Message-ID: <20070101232045.CDEA610072@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 00:20:43 2007
New Revision: 36100
Modified:
pypy/dist/pypy/translator/js/_class.py
pypy/dist/pypy/translator/js/asmgen.py
pypy/dist/pypy/translator/js/database.py
pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
pypy/dist/pypy/translator/js/function.py
pypy/dist/pypy/translator/js/opcodes.py
pypy/dist/pypy/translator/js/test/runtest.py
pypy/dist/pypy/translator/js/test/test_rpython.py
Log:
A bit of refactoring regarding class attributes and such. Mostly whack whack whack here and there. Killed some skips, some stay still.
Modified: pypy/dist/pypy/translator/js/_class.py
==============================================================================
--- pypy/dist/pypy/translator/js/_class.py (original)
+++ pypy/dist/pypy/translator/js/_class.py Tue Jan 2 00:20:43 2007
@@ -44,6 +44,8 @@
self.ilasm = ilasm
ilasm.begin_function(self.name, [])
+ # we need to copy here all the arguments
+ self.copy_class_attributes(ilasm)
ilasm.end_function()
# begin to_String method
@@ -66,8 +68,13 @@
f = self.db.genoo.Function(self.db, m_meth.graph, m_name, is_method = True, _class = self.name)
f.render(ilasm)
-
self.db.record_class(self.classdef, self.name)
+ def copy_class_attributes(self, ilasm):
+ for field_name, (field_type, field_value) in self.classdef._fields.items():
+ ilasm.load_str("this")
+ self.db.load_const(field_type, field_value, ilasm)
+ ilasm.set_field(None, field_name)
+
def basename(self, name):
return name.replace('.', '_')#[-1]
Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py (original)
+++ pypy/dist/pypy/translator/js/asmgen.py Tue Jan 2 00:20:43 2007
@@ -213,9 +213,12 @@
self.right_hand.append("%s.%s"%(self.right_hand.pop(), name))
def new(self, obj):
- log("New: %r"%obj)
+ #log("New: %r"%obj)
self.right_hand.append("new %s()"%obj)
+ def runtimenew(self):
+ self.right_hand.append("new %s()" % self.right_hand.pop())
+
def load_self(self):
self.right_hand.append("this")
Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py (original)
+++ pypy/dist/pypy/translator/js/database.py Tue Jan 2 00:20:43 2007
@@ -110,6 +110,8 @@
if self.is_primitive(type_):
return None
const = AbstractConst.make(self, value)
+ if not const:
+ return None
try:
if retval == 'name':
return self.consts[const]
@@ -229,6 +231,11 @@
return DictConst(db, const)
elif isinstance(const, bltregistry._external_type):
return ExtObject(db, const)
+ elif isinstance(const, ootype._class):
+ if const._INSTANCE:
+ return ClassConst(db, const)
+ else:
+ return None
else:
assert False, 'Unknown constant: %s %r' % (const, typeOf(const))
make = staticmethod(make)
@@ -285,32 +292,28 @@
def record_fields(self):
if not self.obj:
return
- # we support only primitives, tuples, strings and lists
-
+ import pdb;pdb.set_trace()
INSTANCE = self.obj._TYPE
- while INSTANCE:
- for i, (_type, val) in INSTANCE._fields.iteritems():
- if _type is not ootype.Void and i.startswith('o'):
- name = self.db.record_const(getattr(self.obj, i), _type, 'const')
- if name is not None:
- self.depends.add(name)
- name.depends_on.add(self)
- INSTANCE = INSTANCE._superclass
+ #while INSTANCE:
+ for i, (_type, val) in INSTANCE._allfields().items():
+ if _type is not ootype.Void:
+ name = self.db.record_const(getattr(self.obj, i), _type, 'const')
+ if name is not None:
+ self.depends.add(name)
+ name.depends_on.add(self)
def init_fields(self, ilasm, const_var, name):
if not self.obj:
return
INSTANCE = self.obj._TYPE
- while INSTANCE:
- for i, (_type, el) in INSTANCE._fields.iteritems():
- if _type is not ootype.Void and i.startswith('o'):
- ilasm.load_local(const_var)
- self.db.load_const(_type, getattr(self.obj, i), ilasm)
- ilasm.set_field(None, "%s.%s"%(name, i))
- ilasm.store_void()
- INSTANCE = INSTANCE._superclass
- #raise NotImplementedError("Default fields of instances")
+ #while INSTANCE:
+ for i, (_type, el) in INSTANCE._allfields().items():
+ if _type is not ootype.Void:
+ ilasm.load_local(const_var)
+ self.db.load_const(_type, getattr(self.obj, i), ilasm)
+ ilasm.set_field(None, "%s.%s"%(name, i))
+ ilasm.store_void()
class RecordConst(AbstractConst):
def get_name(self):
@@ -400,6 +403,26 @@
def init_fields(self, ilasm, const_var, name):
pass
+class ClassConst(AbstractConst):
+ def __init__(self, db, const):
+ super(ClassConst, self).__init__(db, const)
+ self.cts.lltype_to_cts(const._INSTANCE) # force scheduling of class
+
+ def get_name(self):
+ return "const_class"
+
+ def get_key(self):
+ return self.get_name()
+
+ def get_name(self):
+ return self.const._INSTANCE._name.replace(".", "_")
+
+ def init(self, ilasm):
+ ilasm.load_const("%s" % self.get_name())
+
+ #def init_fields(self, ilasm, const_var, name):
+ # pass
+
class BuiltinConst(AbstractConst):
def __init__(self, name):
self.name = name
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Tue Jan 2 00:20:43 2007
@@ -177,7 +177,7 @@
self.wfile.write(data)
-def build_http_server(server_address=('', 8000)):
+def build_http_server(server_address=('', 8001)):
global httpd
httpd = Server(server_address, RequestHandler)
print 'http://127.0.0.1:%d' % (server_address[1],)
Modified: pypy/dist/pypy/translator/js/function.py
==============================================================================
--- pypy/dist/pypy/translator/js/function.py (original)
+++ pypy/dist/pypy/translator/js/function.py Tue Jan 2 00:20:43 2007
@@ -10,7 +10,7 @@
from pypy.translator.cli.option import getoption
from pypy.translator.cli.cts import CTS
from pypy.translator.cli.opcodes import opcodes
-from pypy.translator.cli.metavm import Generator,InstructionList
+from pypy.translator.oosupport.metavm import Generator,InstructionList
from pypy.translator.cli.node import Node
from pypy.translator.cli.class_ import Class
@@ -411,6 +411,12 @@
def call_external_method(self, name, arg_len):
self.ilasm.call_method(None, name, [0]*arg_len)
+
+ def instantiate(self):
+ self.ilasm.runtimenew()
+
+ def downcast(self, TYPE):
+ pass
def load(self, v):
if isinstance(v, flowmodel.Variable):
Modified: pypy/dist/pypy/translator/js/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/js/opcodes.py (original)
+++ pypy/dist/pypy/translator/js/opcodes.py Tue Jan 2 00:20:43 2007
@@ -2,7 +2,7 @@
"""
from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult,\
- InstructionList, New, SetField, GetField, MicroInstruction
+ InstructionList, New, SetField, GetField, MicroInstruction, RuntimeNew
from pypy.translator.oosupport.metavm import _GetFieldDispatcher, _SetFieldDispatcher, \
_CallDispatcher, _MethodDispatcher
@@ -110,6 +110,7 @@
'indirect_call' : [IndirectCall],
'same_as' : SameAs,
'new' : [New],
+ 'runtimenew' : [RuntimeNew],
'instanceof' : [IsInstance],
# objects
Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py (original)
+++ pypy/dist/pypy/translator/js/test/runtest.py Tue Jan 2 00:20:43 2007
@@ -15,6 +15,8 @@
from pypy.translator.transformer.debug import DebugTransformer
from pypy.rlib.nonconst import NonConstant
+from pypy.rpython.llinterp import LLException
+
log = log.runtest
use_browsertest = conftest.option.browser
use_tg = conftest.option.tg
@@ -119,6 +121,8 @@
res = 1e300 * 1e300
elif s == 'NaN':
res = (1e300 * 1e300) / (1e300 * 1e300)
+ elif s.startswith("uncaught exception:"):
+ raise LLException(str(s))
else:
log('javascript result:', s)
try:
@@ -169,9 +173,14 @@
#import exceptions # needed by eval
#try:
#import pdb; pdb.set_trace()
- res = self.interpret(fn, args)
- assert res.startswith('uncaught exception:')
- assert re.search(str(exception), res)
+ try:
+ res = self.interpret(fn, args)
+ except LLException, e:
+ s = e.args[0]
+ assert s.startswith('uncaught exception:')
+ assert re.search(str(exception), s)
+ else:
+ raise AssertionError("Did not raise, returned %s" % res)
#except ExceptionWrapper, ex:
# assert issubclass(eval(ex.class_name), exception)
#else:
Modified: pypy/dist/pypy/translator/js/test/test_rpython.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_rpython.py (original)
+++ pypy/dist/pypy/translator/js/test/test_rpython.py Tue Jan 2 00:20:43 2007
@@ -7,15 +7,10 @@
from pypy.rpython.test.test_rtuple import BaseTestRtuple
from pypy.rpython.test.test_rstr import BaseTestRstr
-py.test.skip("Those tests are totally broken, need deeper look")
-
class TestJsException(JsTest, BaseTestException):
pass
class TestJsClass(JsTest, BaseTestRclass):
- def test_classattr_as_defaults(self):
- py.test.skip("WIP")
-
def test_recursive_prebuilt_instance(self):
py.test.skip("WIP")
@@ -27,19 +22,13 @@
def test_mixin(self):
py.test.skip("WIP")
-
- def test_type(self):
+
+ def test_getattr_on_classes(self):
py.test.skip("WIP")
-
+
def test_hash_preservation(self):
py.test.skip("WIP")
-
- def test_ne(self):
- py.test.skip("WIP")
-
- def test_eq(self):
- py.test.skip("WIP")
-
+
def test_issubclass_type(self):
py.test.skip("WIP")
@@ -49,14 +38,14 @@
def test_recursive_prebuilt_instance_classattr(self):
py.test.skip("WIP")
-##class TestJsList(JsTest, BaseTestRlist):
-## pass
+#class TestJsList(JsTest, BaseTestRlist):
+# pass
##
-##class TestJsPBC(JsTest, BaseTestRPBC):
-## pass
+#class TestJsPBC(JsTest, BaseTestRPBC):
+# pass
##
-##class TestJsRtuple(JsTest, BaseTestRtuple):
-## pass
+#class TestJsRtuple(JsTest, BaseTestRtuple):
+# pass
##
-##class TestJsStr(JsTest, BaseTestRstr):
-## pass
+#class TestJsStr(JsTest, BaseTestRstr):
+# pass
From arigo at codespeak.net Tue Jan 2 15:18:41 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 2 Jan 2007 15:18:41 +0100 (CET)
Subject: [pypy-svn] r36101 - in pypy/dist/pypy/rlib/rctypes: . test
Message-ID: <20070102141841.DB41C1006F@code0.codespeak.net>
Author: arigo
Date: Tue Jan 2 15:18:37 2007
New Revision: 36101
Modified:
pypy/dist/pypy/rlib/rctypes/rctypesobject.py
pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py
Log:
- support for rc_char_p containing None.
- a copyfrom() that is easier to support for llmemory.
Modified: pypy/dist/pypy/rlib/rctypes/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rctypesobject.py Tue Jan 2 15:18:37 2007
@@ -75,12 +75,6 @@
return cls(memblock.addr, memblock)
cls.allocate = staticmethod(allocate1)
- def copyfrom1(self, srcbox):
- assert isinstance(srcbox, cls)
- llmemory.raw_memcopy(srcbox.addr, self.addr, cls.rawsize)
- self._copykeepalives(0, srcbox)
- cls.copyfrom = copyfrom1
-
if hasattr(cls, 'llvalue2value') and not hasattr(cls, 'get_value'):
def get_value(self):
ptr = self.ll_ref(cls.CDATATYPE)
@@ -96,6 +90,18 @@
keepalive_until_here(self)
cls.set_value = set_value
+ if hasattr(cls, 'get_value') and hasattr(cls, 'set_value'):
+ def copyfrom1(self, srcbox):
+ assert isinstance(srcbox, cls)
+ self.set_value(srcbox.get_value())
+ self._copykeepalives(0, srcbox)
+ else:
+ def copyfrom1(self, srcbox):
+ assert isinstance(srcbox, cls)
+ llmemory.raw_memcopy(srcbox.addr, self.addr, cls.rawsize)
+ self._copykeepalives(0, srcbox)
+ cls.copyfrom = copyfrom1
+
def sameaddr(self, otherbox):
return self.addr == otherbox.addr
@@ -199,22 +205,29 @@
num_keepalives = 1
def llvalue2value(p):
- length = strlen(p)
- return charp2string(p, length)
+ if p:
+ length = strlen(p)
+ return charp2string(p, length)
+ else:
+ return None
llvalue2value = staticmethod(llvalue2value)
#def get_value(self): added by __initclass__() above
def set_value(self, string):
- n = len(string)
- rawsize = RCTypesCharP.ITEMOFS * (n + 1)
- targetmemblock = AllocatedRawMemBlock(0, rawsize, zero=False)
- targetaddr = targetmemblock.addr
- a = targetaddr
- for i in range(n):
- a.char[0] = string[i]
- a += RCTypesCharP.ITEMOFS
- a.char[0] = '\x00'
+ if string is not None:
+ n = len(string)
+ rawsize = RCTypesCharP.ITEMOFS * (n + 1)
+ targetmemblock = AllocatedRawMemBlock(0, rawsize, zero=False)
+ targetaddr = targetmemblock.addr
+ a = targetaddr
+ for i in range(n):
+ a.char[0] = string[i]
+ a += RCTypesCharP.ITEMOFS
+ a.char[0] = '\x00'
+ else:
+ targetmemblock = None
+ targetaddr = llmemory.NULL
ptr = self.ll_ref(RCTypesCharP.CDATATYPE)
ptr[0] = llmemory.cast_adr_to_ptr(targetaddr, RCTypesCharP.LLTYPE)
keepalive_until_here(self)
Modified: pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py Tue Jan 2 15:18:37 2007
@@ -158,6 +158,18 @@
res = self.do(func)
assert res == 1
+ def test_char_p_None(self):
+ def func():
+ p = rc_char_p.allocate()
+ assert p.get_value() is None
+ p.set_value("")
+ assert p.get_value() == ""
+ p.set_value("abc")
+ assert p.get_value() == "abc"
+ p.set_value(None)
+ assert p.get_value() is None
+ self.do(func)
+
def test_char_array(self):
def func():
a = RFixedArray(rc_char, 10).allocate()
From fijal at codespeak.net Tue Jan 2 15:19:19 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 15:19:19 +0100 (CET)
Subject: [pypy-svn] r36102 - in pypy/dist/pypy: rpython/ootypesystem
translator/js/test
Message-ID: <20070102141919.E91AE10071@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 15:19:17 2007
New Revision: 36102
Added:
pypy/dist/pypy/rpython/ootypesystem/extdesc.py (contents, props changed)
Modified:
pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
pypy/dist/pypy/translator/js/test/test_bltn.py
Log:
Refactored bltregistry a bit, mostly deleting unused code and splitting into two files.
Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Tue Jan 2 15:19:17 2007
@@ -1,7 +1,5 @@
-""" External objects registry, defining two types of object:
-1. Those who need to be flown normally, but needs different representation in the backend
-2. Those who does not need to be flown
+""" External objects registry,
"""
from pypy.annotation import model as annmodel
@@ -11,33 +9,7 @@
from pypy.rpython.lltypesystem.lltype import frozendict, isCompatibleType
from types import MethodType
from pypy.rpython.extregistry import ExtRegistryEntry
-
-class ArgDesc(object):
- def __init__(self, name, ex_value):
- self.name = name
- self.example = ex_value
-
- def __repr__(self):
- return "" % (self.name, self.example)
-
-class MethodDesc(object):
- def __init__(self, args, retval = None):
- self.num = 0
- self.args = [self.convert_val(arg) for arg in args]
- self.retval = self.convert_val(retval)
- self.example = self
-
- def convert_val(self, val):
- if isinstance(val, ArgDesc) or isinstance(val, MethodDesc):
- return val
- elif isinstance(val, tuple):
- return ArgDesc(*val)
- else:
- self.num += 1
- return ArgDesc('v%d' % (self.num-1), val)
-
- def __repr__(self):
- return "" % (self.args,)
+from pypy.rpython.ootypesystem.extdesc import MethodDesc, ArgDesc
class CallableEntry(ExtRegistryEntry):
_type_ = MethodDesc
@@ -46,17 +18,15 @@
# because we have no good annotation
# let's cheat a little bit for a while...
bookkeeper = getbookkeeper()
- # hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack
+ # hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack,
values = ["v%d"%i for i in xrange(len(self.instance.args))]
lb = eval("lambda %s: None" % ",".join(values))
- s = annmodel.SomePBC([bookkeeper.getdesc(lb)])
- #bookkeeper.pbc_call(s, bookkeeper.build_args("simple_call", [bookkeeper.annotation_from_example(arg.example) for arg in self.instance.args]))
- return s
+ return annmodel.SomePBC([bookkeeper.getdesc(lb)])
class BasicMetaExternal(type):
def _is_compatible(type2):
return type(type2) is BasicMetaExternal
-
+
def __new__(self, _name, _type, _vars):
retval = type.__new__(self, _name, _type, _vars)
if not retval._methods:
@@ -108,12 +78,6 @@
class Analyzer(object):
def __init__(self, name, value, s_retval, s_args):
self.name = name
- # dirty hack
- # FIXME: to replace in future
- #if value.args[-1].name == 'callback':
- # itervalues = value.args[:-1]
- #else:
- # itervalues = value.args
self.args, self.retval = value.args, value.retval
self.s_retval = s_retval
self.s_args = s_args
@@ -131,17 +95,12 @@
__name__ = "ExternalType"
def __init__(self, _class):
- # FIXME: We want to support inheritance at some point, or maybe not
self._class_ = _class
self._name = str(_class)
self._superclass = None
self._root = True
self.updated = False
self._data = frozendict(_class._fields), frozendict(_class._methods)
- #self._methods = _class._methods
- #_methods = dict([(i,ootype._meth(ootype.Meth(*val))) for i,val in _class._methods.iteritems()])
- #ootype.Instance.__init__(self, str(_class), None, _class._fields, _methods, True)
- #self.attr = {}
def update_fields(self, _fields):
for i, val in _fields.iteritems():
@@ -195,14 +154,6 @@
def _defl(self):
return _external_type(self)
-## def _defl(self):
-## raise AttributeError()
-## return self._null
-##
-## def _example(self):
-## raise AttributeError()return new(self)
-##
-
class _external_type(object):
def __init__(self, et):
@@ -230,20 +181,13 @@
class Entry_basicexternal(ExtRegistryEntry):
_type_ = BasicExternal.__metaclass__
- #def compute_annotation(self, *args):
- # return annmodel.SomeOOInstance(ootype=BasicExternal)
-
def compute_result_annotation(self):
- #return annmodel.SomeExternalBuiltin(ExternalType.get(self.instance))
return annmodel.SomeExternalBuiltin(self.bookkeeper.getexternaldesc(self.instance))
- #Ereturn annmodel.SomeOOInstance(ExternalType.get(self.instance))
def specialize_call(self, hop):
- #assert isinstance(hop.args_s[0], annmodel.SomeOOInstance)\
- # and hop.args_s[0].ootype is Externaltype
value = hop.r_result.lowleveltype
return hop.genop('new', [Constant(value, concretetype=ootype.Void)], \
resulttype = value)
-def rebuild_basic_external():
- ExternalType.class_dict = {}
+#def rebuild_basic_external():
+# ExternalType.class_dict = {}
Added: pypy/dist/pypy/rpython/ootypesystem/extdesc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/ootypesystem/extdesc.py Tue Jan 2 15:19:17 2007
@@ -0,0 +1,37 @@
+
+""" extdesc - some descriptions for external entries
+"""
+
+class ArgDesc(object):
+ """ Description of argument, given as name + example value
+ (used to deduce type)
+ """
+ def __init__(self, name, ex_value):
+ self.name = name
+ self.example = ex_value
+
+ def __repr__(self):
+ return "" % (self.name, self.example)
+
+class MethodDesc(object):
+ """ Description of method to be external,
+ args are taken from examples given as keyword arguments or as args,
+ return value must be specified, because this will not be flown
+ """
+ def __init__(self, args, retval = None):
+ self.num = 0
+ self.args = [self.convert_val(arg) for arg in args]
+ self.retval = self.convert_val(retval)
+ self.example = self
+
+ def convert_val(self, val):
+ if isinstance(val, ArgDesc) or isinstance(val, MethodDesc):
+ return val
+ elif isinstance(val, tuple):
+ return ArgDesc(*val)
+ else:
+ self.num += 1
+ return ArgDesc('v%d' % (self.num-1), val)
+
+ def __repr__(self):
+ return "" % (self.args,)
Modified: pypy/dist/pypy/translator/js/test/test_bltn.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_bltn.py (original)
+++ pypy/dist/pypy/translator/js/test/test_bltn.py Tue Jan 2 15:19:17 2007
@@ -3,12 +3,11 @@
import py
-from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc,\
- rebuild_basic_external
+from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
from pypy.translator.js.test.runtest import compile_function, check_source_contains
-def setup_function(fun):
- rebuild_basic_external()
+#def setup_function(fun):
+# rebuild_basic_external()
# check rendering dom.get_document()
def test_simple_builtin():
From arigo at codespeak.net Tue Jan 2 15:31:54 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 2 Jan 2007 15:31:54 +0100 (CET)
Subject: [pypy-svn] r36103 - in pypy/dist/pypy/rlib/rctypes: . test
Message-ID: <20070102143154.8CD3F1006F@code0.codespeak.net>
Author: arigo
Date: Tue Jan 2 15:31:50 2007
New Revision: 36103
Added:
pypy/dist/pypy/rlib/rctypes/rchar_p.py (contents, props changed)
pypy/dist/pypy/rlib/rctypes/test/test_rchar_p.py
- copied, changed from r36079, pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
- copied, changed from r36072, pypy/dist/pypy/rpython/rctypes/test/test_rstruct.py
Modified:
pypy/dist/pypy/rlib/rctypes/implementation.py
pypy/dist/pypy/rlib/rctypes/rstruct.py
Log:
rchar_p implementation. Some more work on rstruct.
Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py Tue Jan 2 15:31:50 2007
@@ -43,13 +43,16 @@
register_for_metatype = classmethod(register_for_metatype)
def convert(self, x):
- assert isinstance(x, self.ctype)
- key = id(x)
+ if isinstance(x, self.ctype):
+ key = "by_id", id(x)
+ else:
+ key = "by_value", x
+ x = self.ctype(x)
try:
- return self.instance_cache[key]
+ return self.instance_cache[key][0]
except KeyError:
obj = self.new()
- self.instance_cache[key] = obj
+ self.instance_cache[key] = obj, x # keep 'x' alive
self.initialize_prebuilt(obj, x)
return obj
@@ -172,3 +175,4 @@
import pypy.rlib.rctypes.rpointer
import pypy.rlib.rctypes.rstruct
import pypy.rlib.rctypes.rbuiltin
+import pypy.rlib.rctypes.rchar_p
Added: pypy/dist/pypy/rlib/rctypes/rchar_p.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/rctypes/rchar_p.py Tue Jan 2 15:31:50 2007
@@ -0,0 +1,34 @@
+from pypy.rlib.rctypes.implementation import CTypeController
+from pypy.rlib.rctypes import rctypesobject
+
+from ctypes import c_char_p
+
+
+class CCharPCTypeController(CTypeController):
+ knowntype = rctypesobject.rc_char_p
+
+ def new(self, initialvalue=None):
+ obj = rctypesobject.rc_char_p.allocate()
+ obj.set_value(initialvalue)
+ return obj
+
+ def initialize_prebuilt(self, obj, x):
+ string = x.value
+ obj.set_value(string)
+
+ def get_value(self, obj):
+ return obj.get_value()
+
+ def set_value(self, obj, string):
+ obj.set_value(string)
+
+ # ctypes automatically unwraps the c_char_p() instances when
+ # they are returned by most operations
+ return_value = get_value
+ store_value = set_value
+
+ def is_true(self, obj):
+ return obj.get_value() is not None
+
+
+CCharPCTypeController.register_for_type(c_char_p)
Modified: pypy/dist/pypy/rlib/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rstruct.py Tue Jan 2 15:31:50 2007
@@ -1,5 +1,6 @@
from pypy.rlib.rctypes.implementation import CTypeController, getcontroller
from pypy.rlib.rctypes import rctypesobject
+from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.lltypesystem import lltype
from pypy.rlib.unroll import unrolling_iterable
@@ -24,6 +25,7 @@
external = getattr(ctype, '_external_', False)
self.knowntype = rctypesobject.RStruct(ctype.__name__, fields,
c_external = external)
+ self.fieldcontrollers = controllers
# Build a custom new() method where the setting of the fields
# is unrolled
@@ -68,5 +70,33 @@
self.setattr = structsetattr
self.setboxattr = structsetboxattr
+ def initialize_prebuilt(self, obj, x):
+ for name, controller in self.fieldcontrollers:
+ fieldbox = controller.convert(getattr(x, name))
+ self.setboxattr(obj, name, fieldbox)
+
StructCTypeController.register_for_metatype(StructType)
+
+# ____________________________________________________________
+
+def offsetof(Struct, fieldname):
+ "Utility function that returns the offset of a field in a structure."
+ return getattr(Struct, fieldname).offset
+
+class OffsetOfFnEntry(ExtRegistryEntry):
+ "Annotation and rtyping of calls to offsetof()"
+ _about_ = offsetof
+
+ def compute_result_annotation(self, s_Struct, s_fieldname):
+ assert s_Struct.is_constant()
+ assert s_fieldname.is_constant()
+ ofs = offsetof(s_Struct.const, s_fieldname.const)
+ assert ofs >= 0
+ s_result = SomeInteger(nonneg=True)
+ s_result.const = ofs
+ return s_result
+
+ def specialize_call(self, hop):
+ ofs = hop.s_result.const
+ return hop.inputconst(lltype.Signed, ofs)
From fijal at codespeak.net Tue Jan 2 15:35:26 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 15:35:26 +0100 (CET)
Subject: [pypy-svn] r36104 - pypy/dist/pypy/translator/js/test
Message-ID: <20070102143526.56AF01006F@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 15:35:25 2007
New Revision: 36104
Modified:
pypy/dist/pypy/translator/js/test/test_basicexternal.py
Log:
Added a test which (suprisingly) passes
Modified: pypy/dist/pypy/translator/js/test/test_basicexternal.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_basicexternal.py (original)
+++ pypy/dist/pypy/translator/js/test/test_basicexternal.py Tue Jan 2 15:35:25 2007
@@ -34,18 +34,32 @@
fun = compile_function(be_fun, [])
check_source_contains(fun, "\.some_code")
-def test_basicexternal_raise():
- py.test.skip("Constant BasicExternals not implemented")
- def raising_fun():
- try:
- b = B()
- except:
- pass
- else:
- return 3
+##def test_basicexternal_raise():
+## #py.test.skip("Constant BasicExternals not implemented")
+## def raising_fun():
+## try:
+## b = B()
+## except:
+## pass
+## else:
+## return 3
+##
+## fun = compile_function(raising_fun, [])
+## assert fun() == 3
+
+class EE(BasicExternal):
+ @described(retval=3)
+ def bb(self):
+ pass
- fun = compile_function(raising_fun, [])
- assert fun() == 3
+ee = EE()
+
+def test_prebuild_basicexternal():
+ def tt_fun():
+ ee.bb()
+
+ fun = compile_function(tt_fun, [])
+ check_source_contains(fun, "ee.bb\(")
class C(BasicExternal):
@described(retval=3)
From arigo at codespeak.net Tue Jan 2 15:58:08 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 2 Jan 2007 15:58:08 +0100 (CET)
Subject: [pypy-svn] r36105 - pypy/extradoc/planning/secprototype
Message-ID: <20070102145808.0B43E10074@code0.codespeak.net>
Author: arigo
Date: Tue Jan 2 15:58:06 2007
New Revision: 36105
Added:
pypy/extradoc/planning/secprototype/talk-outline.txt
- copied unchanged from r36104, pypy/extradoc/planning/secprototype/talk.txt
Removed:
pypy/extradoc/planning/secprototype/talk.txt
Log:
Move out of the way.
From fijal at codespeak.net Tue Jan 2 16:16:17 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 16:16:17 +0100 (CET)
Subject: [pypy-svn] r36106 - pypy/dist/pypy/rpython/ootypesystem
Message-ID: <20070102151617.B068310077@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 16:16:16 2007
New Revision: 36106
Modified:
pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
Log:
Add value storing for consts
Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Tue Jan 2 16:16:16 2007
@@ -152,12 +152,13 @@
return "%s %s" % (self.__name__, self._name)
def _defl(self):
- return _external_type(self)
-
+ return _external_type(self, None)
+
class _external_type(object):
- def __init__(self, et):
+ def __init__(self, et, value):
self._TYPE = et
+ self.value = value
class Entry_basicexternalmeta(ExtRegistryEntry):
_metatype_ = BasicMetaExternal
From fijal at codespeak.net Tue Jan 2 16:16:47 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 16:16:47 +0100 (CET)
Subject: [pypy-svn] r36107 - pypy/dist/pypy/rpython
Message-ID: <20070102151647.ABFD810078@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 16:16:45 2007
New Revision: 36107
Modified:
pypy/dist/pypy/rpython/rexternalobj.py
Log:
Forgotten to check that in
Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py (original)
+++ pypy/dist/pypy/rpython/rexternalobj.py Tue Jan 2 16:16:45 2007
@@ -36,9 +36,7 @@
def convert_const(self, value):
from pypy.rpython.ootypesystem.bltregistry import ExternalType,_external_type
- #if value is None:
- # return lltype.Void
- return _external_type(self.knowntype)
+ return _external_type(self.knowntype, value)
def rtype_getattr(self, hop):
attr = hop.args_s[1].const
From fijal at codespeak.net Tue Jan 2 16:18:20 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 16:18:20 +0100 (CET)
Subject: [pypy-svn] r36108 - in pypy/dist/pypy: doc/js translator/js
translator/js/demo/jsdemo
translator/js/demo/jsdemo/djangoping translator/js/examples
translator/js/modules translator/js/modules/test
translator/js/test translator/js/tutorial
Message-ID: <20070102151820.6F6B710078@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 16:18:14 2007
New Revision: 36108
Modified:
pypy/dist/pypy/doc/js/webapps_with_pypy.txt
pypy/dist/pypy/translator/js/asmgen.py
pypy/dist/pypy/translator/js/database.py
pypy/dist/pypy/translator/js/demo/jsdemo/consserv.py
pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py
pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py
pypy/dist/pypy/translator/js/demo/jsdemo/example.py
pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
pypy/dist/pypy/translator/js/examples/console.py
pypy/dist/pypy/translator/js/examples/start_bnb.py
pypy/dist/pypy/translator/js/helper.py
pypy/dist/pypy/translator/js/jsbuiltin.py
pypy/dist/pypy/translator/js/modules/dom.py
pypy/dist/pypy/translator/js/modules/test/test_dom.py
pypy/dist/pypy/translator/js/test/test_basicexternal.py
pypy/dist/pypy/translator/js/test/test_bltn.py
pypy/dist/pypy/translator/js/test/test_main.py
pypy/dist/pypy/translator/js/tutorial/step3.py
Log:
Factored out use of (deprecated) get_document() and get_window(), one might use document and window instead. This needed implementation of prebuilt BasicExternal rendering. Killed some dead code in between.
Modified: pypy/dist/pypy/doc/js/webapps_with_pypy.txt
==============================================================================
--- pypy/dist/pypy/doc/js/webapps_with_pypy.txt (original)
+++ pypy/dist/pypy/doc/js/webapps_with_pypy.txt Tue Jan 2 16:18:14 2007
@@ -89,4 +89,4 @@
XXX hands-on guide to writing guestbook or something
-.. _`RPython`: ../coding-guide.html#restricted-python
\ No newline at end of file
+.. _`RPython`: ../coding-guide.html#restricted-python
Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py (original)
+++ pypy/dist/pypy/translator/js/asmgen.py Tue Jan 2 16:18:14 2007
@@ -226,7 +226,8 @@
if len(self.right_hand) == 0:
return
v = self.right_hand.pop()
- if v is not None:
+ # if v is not calling anything, drop it
+ if v is not None and v.find('('):
self.codegenerator.writeline(v+";")
#self.right_hand.pop()
Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py (original)
+++ pypy/dist/pypy/translator/js/database.py Tue Jan 2 16:18:14 2007
@@ -42,18 +42,8 @@
self.name_manager = JavascriptNameManager(self)
self.pending_consts = []
self.cts = self.genoo.TypeSystem(self)
- self.prepare_builtins()
self.proxies = []
- def prepare_builtins(self):
- # Document Object Model elements
- #for module in [dom]:
- # for i in dir(module):
- # if not i.startswith('__'):
- # # FIXME: shit, strange way of doing it
- # self.consts[BuiltinConst(module[i])] = i
- return
-
def is_primitive(self, type_):
if type_ in [Void, Bool, Float, Signed, Unsigned, SignedLongLong, UnsignedLongLong, Char, UniChar, ootype.StringBuilder] or \
isinstance(type_,ootype.StaticMethod):
@@ -491,4 +481,7 @@
ilasm.new(self.get_name())
else:
# Otherwise they just exist, or it's not implemented
- ilasm.load_str("undefined")
+ if not hasattr(self.const.value, '_render_name'):
+ raise ValueError("Prebuilt constant %s has no attribute _render_name,"
+ "don't know how to render" % self.const.value)
+ ilasm.load_str(self.const.value._render_name)
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/consserv.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/consserv.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/consserv.py Tue Jan 2 16:18:14 2007
@@ -13,7 +13,7 @@
from pypy.translator.js.test.runtest import compile_function
-from pypy.translator.js.modules.dom import Node, get_document, setTimeout,\
+from pypy.translator.js.modules.dom import Node, setTimeout,\
alert
#from pypy.translator.js.modules.xmlhttp import XMLHttpRequest
from pypy.translator.js.modules.mochikit import logDebug, createLoggingPane, log
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/controllers.py Tue Jan 2 16:18:14 2007
@@ -6,6 +6,7 @@
from pypy.translator.js.test.runtest import compile_function
from pypy.translator.js.modules import dom,xmlhttp
+from pypy.translator.js.modules.dom import document
import thread
import os
@@ -14,7 +15,6 @@
pass
def js_fun():
- document = dom.get_document()
obj = document.createElement('img')
obj.id = 'gfx'
obj.setAttribute('style', 'position:absolute; top:0; left:0;')
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/djangoping/client.py Tue Jan 2 16:18:14 2007
@@ -22,7 +22,7 @@
def callback(data):
mochikit.logDebug("Got response: " + data["response"])
- log = dom.get_document().getElementById("log")
+ log = dom.document.getElementById("log")
mochikit.logDebug("got log element")
try:
s = "" + data["response"] + "
"
@@ -39,7 +39,7 @@
def ping_init():
mochikit.createLoggingPane(True)
- button = dom.get_document().getElementById("doping")
+ button = dom.document.getElementById("doping")
button.onclick = doping_onclick
mochikit.logDebug("Ping button setup")
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/example.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/example.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/example.py Tue Jan 2 16:18:14 2007
@@ -6,7 +6,7 @@
from pypy.translator.js.demo.jsdemo import support
-from pypy.translator.js.modules.dom import setTimeout, get_document
+from pypy.translator.js.modules.dom import setTimeout, document
from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal
from pypy.translator.js import commproxy
@@ -31,7 +31,7 @@
httpd = None
def callback(data):
- get_document().getElementById("counter").innerHTML = data['counter']
+ document.getElementById("counter").innerHTML = data['counter']
runjs()
def runjs():
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Tue Jan 2 16:18:14 2007
@@ -12,7 +12,7 @@
import sys, os, cStringIO
from cgi import parse_qs
-from pypy.translator.js.modules.dom import setTimeout, get_document
+from pypy.translator.js.modules.dom import setTimeout, document
from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal
from pypy.translator.js import commproxy
from pypy.translator.js.modules.mochikit import escapeHTML
@@ -46,14 +46,14 @@
httpd = None
def callback(data):
- inp_elem = get_document().getElementById("inp")
+ inp_elem = document.getElementById("inp")
inp_elem.disabled = False
answer = data.get('answer', '')
add_text(answer)
inp_elem.focus()
def add_text(text):
- data_elem = get_document().getElementById("data")
+ data_elem = document.getElementById("data")
data_elem.innerHTML += escapeHTML(text)
class Storage(object):
@@ -66,7 +66,7 @@
def keypressed(key):
kc = key.keyCode
if kc == ord("\r"):
- inp_elem = get_document().getElementById("inp")
+ inp_elem = document.getElementById("inp")
cmd = inp_elem.value
if storage.level == 0:
add_text(">>> %s\n" % (cmd,))
@@ -85,8 +85,8 @@
storage.level = 0
def setup_page():
- get_document().onkeypress = keypressed
- get_document().getElementById("inp").focus()
+ document.onkeypress = keypressed
+ document.getElementById("inp").focus()
class Server(HTTPServer, BasicExternal):
# Methods and signatures how they are rendered for JS
Modified: pypy/dist/pypy/translator/js/examples/console.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/console.py (original)
+++ pypy/dist/pypy/translator/js/examples/console.py Tue Jan 2 16:18:14 2007
@@ -12,7 +12,7 @@
conftest.option.browser = "default"
from pypy.translator.js.test.runtest import compile_function
-from pypy.translator.js.modules.dom import Node, get_document, setTimeout, \
+from pypy.translator.js.modules.dom import Node, document, setTimeout, \
alert
#from pypy.translator.js.modules.xmlhttp import XMLHttpRequest
from pypy.translator.js.modules.mochikit import logDebug, createLoggingPane, log
@@ -27,7 +27,7 @@
self.indent_level = 0
def initialise(self):
- self.elem = get_document().getElementById("data")
+ self.elem = document.getElementById("data")
def add_data(self, data):
if self.indent_level == 0 and data == "":
@@ -51,18 +51,17 @@
def onchange(key):
kc = key.keyCode
if kc == ord("\r"):
- inp_elem = get_document().getElementById("inp")
+ inp_elem = document.getElementById("inp")
inp_elem.value = console.add_data(inp_elem.value)
def test_run_console():
def some_fun():
- #cons = get_document().getElementById("data")
#write_start(cons)
createLoggingPane(True)
console.initialise()
#data_field = get_document().getElementById("data")
#console.onload(data_field)
- get_document().onkeypress = onchange
+ document.onkeypress = onchange
#get_document().onkeyup = onchangedown
print "It's not working"
Modified: pypy/dist/pypy/translator/js/examples/start_bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/start_bnb.py (original)
+++ pypy/dist/pypy/translator/js/examples/start_bnb.py Tue Jan 2 16:18:14 2007
@@ -12,7 +12,7 @@
conftest.option.browser = "default"
from pypy.translator.js.test.runtest import compile_function
-from pypy.translator.js.modules.dom import get_document
+from pypy.translator.js.modules.dom import document
from pypy.translator.js.modules.xmlhttp import XMLHttpRequest
from pypy.translator.js.modules.mochikit import log, logWarning, createLoggingPane, logDebug
from pypy.translator.js.modules.bltns import date
@@ -74,10 +74,10 @@
# img = self.sprite_queues[icon_code].pop()
#except IndexError:
stats.n_sprites += 1
- img = get_document().createElement("img")
+ img = document.createElement("img")
img.setAttribute("src", self.filenames[icon_code])
img.setAttribute("style", 'position:absolute; left:'+x+'px; top:'+y+'px; visibility:visible')
- get_document().getElementById("playfield").appendChild(img)
+ document.getElementById("playfield").appendChild(img)
try:
self.sprites[s].style.visibility = "hidden"
# FIXME: We should delete it
@@ -144,23 +144,23 @@
def appendPlayfield(msg):
bgcolor = '#000000'
- get_document().body.setAttribute('bgcolor', bgcolor)
- div = get_document().createElement("div")
+ document.body.setAttribute('bgcolor', bgcolor)
+ div = document.createElement("div")
div.setAttribute("id", "playfield")
div.setAttribute('width', msg['width'])
div.setAttribute('height', msg['height'])
div.setAttribute('style', 'position:absolute; top:0px; left:0px')
- get_document().body.appendChild(div)
+ document.body.appendChild(div)
def appendPlayfieldXXX():
bgcolor = '#000000'
- get_document().body.setAttribute('bgcolor', bgcolor)
- div = get_document().createElement("div")
+ document.body.setAttribute('bgcolor', bgcolor)
+ div = document.createElement("div")
div.setAttribute("id", "playfield")
div.setAttribute('width', 500)
div.setAttribute('height', 250)
div.setAttribute('style', 'position:absolute; top:0px; left:0px')
- get_document().body.appendChild(div)
+ document.body.appendChild(div)
def process_message(msg):
if msg['type'] == 'def_playfield':
@@ -247,8 +247,8 @@
# stats.__init__()
# sm.__init__()
# sm.begin_clean_sprites()
- # playfield = get_document().getElementById("playfield")
- # get_document().body.removeChild(playfield)
+ # playfield = document.getElementById("playfield")
+ # document.body.removeChild(playfield)
# appendPlayfieldXXX()
## count = int(msgs['add_data'][0]['n'])
@@ -266,20 +266,20 @@
for msg in msgs['messages']:
process_message(msg)
stats.register_frame()
- get_document().title = str(stats.n_sprites) + " sprites " + str(stats.fps)
+ document.title = str(stats.n_sprites) + " sprites " + str(stats.fps)
def session_dispatcher(msgs):
BnbRootInstance.get_message(player.id, "", bnb_dispatcher)
def run_bnb():
def bnb():
- genjsinfo = get_document().getElementById("genjsinfo")
- get_document().body.removeChild(genjsinfo)
+ genjsinfo = document.getElementById("genjsinfo")
+ document.body.removeChild(genjsinfo)
createLoggingPane(True)
log("keys: [0-9] to select player, [wsad] to walk around")
BnbRootInstance.initialize_session(session_dispatcher)
- get_document().onkeydown = keydown
- get_document().onkeyup = keyup
+ document.onkeydown = keydown
+ document.onkeyup = keyup
from pypy.translator.js.demo.jsdemo.bnb import BnbRoot
fn = compile_function(bnb, [], root = BnbRoot, run_browser = False)
Modified: pypy/dist/pypy/translator/js/helper.py
==============================================================================
--- pypy/dist/pypy/translator/js/helper.py (original)
+++ pypy/dist/pypy/translator/js/helper.py Tue Jan 2 16:18:14 2007
@@ -2,7 +2,7 @@
""" Some helpers
"""
-from pypy.translator.js.modules.dom import get_document
+from pypy.translator.js.modules.dom import document
def escape(s):
#return s.replace("&", "&").replace("<", "<").replace(">", ">"). \
@@ -10,23 +10,23 @@
return s
def create_debug_div():
- debug_div = get_document().createElement("div")
+ debug_div = document.createElement("div")
debug_div.setAttribute("id", "debug_div")
# XXX attach it somewhere...
- #body = get_document().getElementsByTagName('body')[0]
- get_document().childNodes[0].childNodes[1].appendChild(debug_div)
+ #body = document.getElementsByTagName('body')[0]
+ document.childNodes[0].childNodes[1].appendChild(debug_div)
return debug_div
def __show_traceback(tb, exc):
- debug_div = get_document().getElementById("debug_div")
+ debug_div = document.getElementById("debug_div")
if not debug_div:
# create div here
debug_div = create_debug_div()
- pre_div = get_document().createElement("pre")
+ pre_div = document.createElement("pre")
pre_div.style.color = "#FF0000"
debug_div.appendChild(pre_div)
- txt = get_document().createTextNode("")
+ txt = document.createTextNode("")
pre_div.appendChild(txt)
for tb_entry in tb[1:]:
# list of tuples...
Modified: pypy/dist/pypy/translator/js/jsbuiltin.py
==============================================================================
--- pypy/dist/pypy/translator/js/jsbuiltin.py (original)
+++ pypy/dist/pypy/translator/js/jsbuiltin.py Tue Jan 2 16:18:14 2007
@@ -14,17 +14,12 @@
self.builtin_map = {
'll_js_jseval' : CallBuiltin('eval'),
- #'ll_newlist' : CallBuiltin('newlist'),
- #'ll_alloc_and_set' : CallBuiltin('alloc_and_set'),
- 'get_document' : lambda g,op: g.ilasm.load_const('document'),
'set_on_keydown' : SetOnEvent('onkeydown'),
'set_on_keyup' : SetOnEvent('onkeyup'),
'setTimeout' : SetTimeout,
- #'xmlSetCallback' : XmlSetCallback,
'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]),
'll_strconcat' : InstructionList([PushAllArgs, '+']),
'll_int' : CallBuiltin('parseInt'),
- #'ll_int' : lambda g,op: Call._render_builtin(g, 'parseInt', [op.args[0], op.args[0]]),
'alert' : CallBuiltin('alert'),
'seval' : CallBuiltin('seval'),
'date': NewBuiltin('Date'),
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Tue Jan 2 16:18:14 2007
@@ -87,7 +87,7 @@
def __setattr__(self, name, value):
"""set an attribute on the wrapped node"""
- if name in dir(self):
+ if name in dir(self) or name.startswith('_'):
return super(Node, self).__setattr__(name, value)
if name not in self._fields:
raise NameError, name
@@ -303,18 +303,10 @@
func()
#pass
-# some helper functions (XXX imo these can go, but the code seems to use them
-# a lot... isn't it possible to just use dom.window and dom.document instead?)
-
window = Window()
-
-def get_document():
- return window.document
-get_document.suggested_primitive = True
-
-def get_window():
- return window
-get_window.suggested_primitive = True
+document = window.document
+window._render_name = 'window'
+document._render_name = 'document'
# rtyper stuff
@@ -691,8 +683,6 @@
'charCode' : 12,
})
-get_window.suggested_primitive = True
-get_document.suggested_primitive = True
setTimeout.suggested_primitive = True
# the following code wraps minidom nodes with Node classes, and makes
Modified: pypy/dist/pypy/translator/js/modules/test/test_dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/test/test_dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/test/test_dom.py Tue Jan 2 16:18:14 2007
@@ -19,7 +19,7 @@
def get_window():
if TRANSLATING:
- return dom.get_window()
+ return dom.window
else:
return dom.Window()
Modified: pypy/dist/pypy/translator/js/test/test_basicexternal.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_basicexternal.py (original)
+++ pypy/dist/pypy/translator/js/test/test_basicexternal.py Tue Jan 2 16:18:14 2007
@@ -14,6 +14,7 @@
pass
a = A()
+a._render_name = 'a'
class B(object):
pass
@@ -23,7 +24,7 @@
a.some_code("aa")
fun = compile_function(dec_fun, [])
- check_source_contains(fun, "\.some_code")
+ assert check_source_contains(fun, "\.some_code")
def test_basicexternal_element():
def be_fun():
@@ -32,7 +33,7 @@
b.a.some_code("aa")
fun = compile_function(be_fun, [])
- check_source_contains(fun, "\.some_code")
+ assert check_source_contains(fun, "\.some_code")
##def test_basicexternal_raise():
## #py.test.skip("Constant BasicExternals not implemented")
@@ -53,13 +54,14 @@
pass
ee = EE()
+ee._render_name = 'ee'
def test_prebuild_basicexternal():
def tt_fun():
ee.bb()
fun = compile_function(tt_fun, [])
- check_source_contains(fun, "ee.bb\(")
+ assert check_source_contains(fun, "EE = ee")
class C(BasicExternal):
@described(retval=3)
@@ -67,6 +69,7 @@
pass
c = C()
+c._render_name = 'c'
def test_basicexternal_raise_method_call():
def raising_method_call():
@@ -88,6 +91,7 @@
D._fields['c'] = [D(),D()]
d = D()
+d._render_name = 'd'
def test_basicexternal_list():
def getaa(item):
Modified: pypy/dist/pypy/translator/js/test/test_bltn.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_bltn.py (original)
+++ pypy/dist/pypy/translator/js/test/test_bltn.py Tue Jan 2 16:18:14 2007
@@ -6,14 +6,11 @@
from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
from pypy.translator.js.test.runtest import compile_function, check_source_contains
-#def setup_function(fun):
-# rebuild_basic_external()
-
-# check rendering dom.get_document()
+# check rendering dom.document
def test_simple_builtin():
- from pypy.translator.js.modules.dom import get_document
+ from pypy.translator.js.modules.dom import document
def test_document_call():
- return get_document().getElementById("some_id")
+ return document.getElementById("some_id")
fn = compile_function(test_document_call, [])
assert check_source_contains(fn, "= document")
@@ -42,6 +39,7 @@
assert check_source_contains(fn, "loadJSONDoc\('some_method'")
SomeNodeInstance = SomeNode()
+SomeNodeInstance._render_name = 's'
# next will try out the callback
def test_callback():
@@ -58,7 +56,7 @@
from pypy.translator.js.modules import dom
def getaa(tname):
- return dom.get_document().getElementsByTagName(tname)[0].nodeValue
+ return dom.document.getElementsByTagName(tname)[0].nodeValue
def some_stuff():
one = getaa("some")
Modified: pypy/dist/pypy/translator/js/test/test_main.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_main.py (original)
+++ pypy/dist/pypy/translator/js/test/test_main.py Tue Jan 2 16:18:14 2007
@@ -17,6 +17,7 @@
method = described(retval={'a':'a'})(method)
a = A()
+a._render_name = 'a'
def fun(x='3'):
return a.method({'a':x})['a']
Modified: pypy/dist/pypy/translator/js/tutorial/step3.py
==============================================================================
--- pypy/dist/pypy/translator/js/tutorial/step3.py (original)
+++ pypy/dist/pypy/translator/js/tutorial/step3.py Tue Jan 2 16:18:14 2007
@@ -12,7 +12,7 @@
from pypy.translator.js.examples import server
from pypy.translator.js.main import rpython2javascript
-from pypy.translator.js.modules import dom
+from pypy.translator.js.modules.dom import document
# dom manipulating module
HTML = """
@@ -33,17 +33,15 @@
# these are exposed functions
def addrow():
- doc = dom.get_document()
-
# we need to call a helper, similiar to document in JS
- tr = doc.createElement("tr")
- td = doc.createElement("td")
- td.appendChild(doc.createTextNode("A row"))
+ tr = document.createElement("tr")
+ td = document.createElement("td")
+ td.appendChild(document.createTextNode("A row"))
tr.appendChild(td)
- dom.get_document().getElementById("atable").appendChild(tr)
+ document.getElementById("atable").appendChild(tr)
def delrow():
- table = dom.get_document().getElementById("atable")
+ table = document.getElementById("atable")
# note -1 working here like in python, this is last element in list
table.removeChild(table.childNodes[-1])
From fijal at codespeak.net Tue Jan 2 16:32:45 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 2 Jan 2007 16:32:45 +0100 (CET)
Subject: [pypy-svn] r36109 - in pypy/dist/pypy/translator/js: . modules
tutorial
Message-ID: <20070102153245.9BD1F1007F@code0.codespeak.net>
Author: fijal
Date: Tue Jan 2 16:32:43 2007
New Revision: 36109
Removed:
pypy/dist/pypy/translator/js/modules/browser.py
Modified:
pypy/dist/pypy/translator/js/asmgen.py
pypy/dist/pypy/translator/js/jsbuiltin.py
pypy/dist/pypy/translator/js/modules/dom.py
pypy/dist/pypy/translator/js/support.py
pypy/dist/pypy/translator/js/tutorial/step2.py
Log:
Kill another suggested_primitive and move back alert to dom, because alert is window.alert
Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py (original)
+++ pypy/dist/pypy/translator/js/asmgen.py Tue Jan 2 16:32:43 2007
@@ -44,7 +44,6 @@
self.subst_table = subst_table
def pop(self):
- #if len(self.l) == 0:
el = self.l.pop()
return self.subst_table.get(el, el)
@@ -193,11 +192,6 @@
def set_static_field(self, _type, namespace, _class, varname):
self.codegenerator.writeline("%s.prototype.%s = %s;"%(_class, varname, self.right_hand.pop()))
- #def load_set_field(self, _type, name):
- # #self.right_hand.append("")
- # #self.codegenerator.writeline("set field %r %r"%(_type, name))
- # pass
-
def set_field(self, useless_parameter, name):
v = self.right_hand.pop()
self.codegenerator.writeline("%s.%s = %s;"%(self.right_hand.pop(), name, v))
@@ -226,10 +220,8 @@
if len(self.right_hand) == 0:
return
v = self.right_hand.pop()
- # if v is not calling anything, drop it
if v is not None and v.find('('):
self.codegenerator.writeline(v+";")
- #self.right_hand.pop()
def begin_consts(self, name):
# load consts, maybe more try to use stack-based features?
@@ -293,6 +285,3 @@
def throw_real(self, s):
self.codegenerator.writeline("throw(%s);"%s)
-
- #def finish ( self ):
- # self . outfile . write ( "%r" % self . right_hand )
Modified: pypy/dist/pypy/translator/js/jsbuiltin.py
==============================================================================
--- pypy/dist/pypy/translator/js/jsbuiltin.py (original)
+++ pypy/dist/pypy/translator/js/jsbuiltin.py Tue Jan 2 16:32:43 2007
@@ -20,7 +20,7 @@
'll_int_str' : lambda g,op: Call._render_builtin_method(g, 'toString' , [op.args[2]]),
'll_strconcat' : InstructionList([PushAllArgs, '+']),
'll_int' : CallBuiltin('parseInt'),
- 'alert' : CallBuiltin('alert'),
+ #'alert' : CallBuiltin('alert'),
'seval' : CallBuiltin('seval'),
'date': NewBuiltin('Date'),
'll_math_fmod' : InstructionList([PushAllArgs, '%']),
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Tue Jan 2 16:32:43 2007
@@ -6,7 +6,7 @@
note that the API is not and will not be complete: more exotic features
will most probably not behave as expected, or are not implemented at all
-
+
http://www.w3.org/DOM/ - main standard
http://www.w3schools.com/dhtml/dhtml_dom.asp - more informal stuff
http://developer.mozilla.org/en/docs/Gecko_DOM_Reference - Gecko reference
@@ -764,6 +764,9 @@
raise ValueError('unsupported node type %s' % (node.nodeType,))
return ''.join(ret)
+def alert(msg):
+ window.alert(msg)
+
# initialization
# set the global 'window' instance to an empty HTML document, override using
Modified: pypy/dist/pypy/translator/js/support.py
==============================================================================
--- pypy/dist/pypy/translator/js/support.py (original)
+++ pypy/dist/pypy/translator/js/support.py Tue Jan 2 16:32:43 2007
@@ -17,7 +17,7 @@
namespace native new null package private protected
public return short static super switch synchronized
this throw throws transient true try typeof
- use var void volatile while with
+ use var void volatile while with alert
'''
for name in reserved_words.split():
self.reserved[name] = True
Modified: pypy/dist/pypy/translator/js/tutorial/step2.py
==============================================================================
--- pypy/dist/pypy/translator/js/tutorial/step2.py (original)
+++ pypy/dist/pypy/translator/js/tutorial/step2.py Tue Jan 2 16:32:43 2007
@@ -23,13 +23,13 @@
from pypy.translator.js.main import rpython2javascript
# here we import rpython -> javascript conversion utility
-from pypy.translator.js.modules import browser
+from pypy.translator.js.modules import dom
# and here we import functions from modules that we want to use
# this is function which will be translated into javascript,
# we can put it in a different module if we like so
def show():
- browser.alert("Alert")
+ dom.alert("Alert")
class Handler(server.TestHandler):
From arigo at codespeak.net Tue Jan 2 17:57:30 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 2 Jan 2007 17:57:30 +0100 (CET)
Subject: [pypy-svn] r36110 - in pypy/extradoc/planning/secprototype: . ui
Message-ID: <20070102165730.F028210071@code0.codespeak.net>
Author: arigo
Date: Tue Jan 2 17:57:29 2007
New Revision: 36110
Added:
pypy/extradoc/planning/secprototype/arch-pypy-basic.png
- copied unchanged from r36104, pypy/extradoc/talk/vancouver/arch-pypy-basic.png
pypy/extradoc/planning/secprototype/arch-translation.png
- copied unchanged from r36104, pypy/extradoc/talk/vancouver/arch-translation.png
pypy/extradoc/planning/secprototype/talk.txt
- copied, changed from r36104, pypy/extradoc/talk/vancouver/talk.txt
pypy/extradoc/planning/secprototype/ui/
- copied from r36104, pypy/extradoc/talk/vancouver/ui/
Log:
(pedronis, cfbolz looking, arigo)
The Zuerich workshop talk (still to be checked).
From antocuni at codespeak.net Tue Jan 2 20:33:21 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 2 Jan 2007 20:33:21 +0100 (CET)
Subject: [pypy-svn] r36111 - pypy/dist/pypy/translator/cli/test
Message-ID: <20070102193321.03B2D10063@code0.codespeak.net>
Author: antocuni
Date: Tue Jan 2 20:33:20 2007
New Revision: 36111
Modified:
pypy/dist/pypy/translator/cli/test/test_list.py
pypy/dist/pypy/translator/cli/test/test_string.py
Log:
skip these tests for now.
Modified: pypy/dist/pypy/translator/cli/test/test_list.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_list.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_list.py Tue Jan 2 20:33:20 2007
@@ -5,3 +5,6 @@
class TestCliList(CliTest, BaseTestRlist):
def test_recursive(self):
py.test.skip("CLI doesn't support recursive lists")
+
+ def test_getitem_exc(self):
+ py.test.skip('fixme!')
Modified: pypy/dist/pypy/translator/cli/test/test_string.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_string.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_string.py Tue Jan 2 20:33:20 2007
@@ -48,3 +48,7 @@
def fn(answer):
return 'the answer is %s' % answer
assert self.ll_to_string(self.interpret(fn, [42])) == 'the answer is 42'
+
+ def test_getitem_exc(self):
+ py.test.skip('fixme!')
+
From santagada at codespeak.net Tue Jan 2 22:03:35 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Tue, 2 Jan 2007 22:03:35 +0100 (CET)
Subject: [pypy-svn] r36112 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070102210335.87C131006F@code0.codespeak.net>
Author: santagada
Date: Tue Jan 2 22:03:29 2007
New Revision: 36112
Modified:
pypy/dist/pypy/lang/js/astgen.py
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
binary and comparison operations ready
Modified: pypy/dist/pypy/lang/js/astgen.py
==============================================================================
--- pypy/dist/pypy/lang/js/astgen.py (original)
+++ pypy/dist/pypy/lang/js/astgen.py Tue Jan 2 22:03:29 2007
@@ -14,6 +14,16 @@
self.left = left
self.right = right
+class BinaryLogicOperator(Node):
+ """super class for binary operators"""
+ def __init__(self, left, right):
+ self.left = left
+ self.right = right
+
+class Or(BinaryLogicOperator): pass
+
+class And(BinaryLogicOperator): pass
+
class Array(Node):
def __init__(self, items=()):
@@ -44,6 +54,8 @@
self.left = left
self.right = right
+class Eq(BinaryOperator): pass
+
class Function(Node):
def __init__(self, name, params, body):
self.name = name
@@ -54,6 +66,8 @@
def __init__(self, expr):
self.expr = expr
+class Ge(BinaryOperator): pass
+
class Gt(BinaryOperator): pass
class Identifier(Node):
@@ -69,6 +83,8 @@
self.thenPart = thenPart
self.elsePart = elsePart
+class In(BinaryOperator): pass
+
class Index(Node):
def __init__(self, left, expr):
self.left = left
@@ -78,8 +94,14 @@
def __init__(self, nodes):
self.nodes = nodes
+class Le(BinaryOperator): pass
+
class Lt(BinaryOperator): pass
+class Minus(BinaryOperator):pass
+
+class Ne(BinaryOperator):pass
+
class New(Node):
def __init__(self, identifier):
self.identifier = identifier
@@ -187,6 +209,12 @@
return Comma(from_dict(d['0']),from_dict(d['1']))
elif tp == 'DOT':
return Dot(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'EQ':
+ return Eq(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'OR':
+ return Or(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'AND':
+ return And(from_dict(d['0']), from_dict(d['1']))
elif tp == 'FUNCTION':
name = d.get('name', '')
body = from_dict(d['body'])
@@ -198,6 +226,8 @@
return f
elif tp == 'GROUP':
return Group(from_dict(d['0']))
+ elif tp == 'GE':
+ return Ge(from_dict(d['0']), from_dict(d['1']))
elif tp == 'GT':
return Gt(from_dict(d['0']), from_dict(d['1']))
elif tp == 'IDENTIFIER':
@@ -213,12 +243,20 @@
else:
elsePart = from_dict(d['elsePart'])
return If(condition,thenPart,elsePart)
+ elif tp == 'IN':
+ return In(from_dict(d['0']), from_dict(d['1']))
elif tp == 'INDEX':
return Index(from_dict(d['0']), from_dict(d['1']))
elif tp == 'LIST':
return List(getlist(d))
+ elif tp == 'LE':
+ return Le(from_dict(d['0']), from_dict(d['1']))
elif tp == 'LT':
return Lt(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'MINUS':
+ return Minus(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'NE':
+ return Ne(from_dict(d['0']), from_dict(d['1']))
elif tp == 'NEW':
return New(d['0']['value'])
elif tp == 'NUMBER':
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Tue Jan 2 22:03:29 2007
@@ -124,29 +124,88 @@
else:
pass
-class __extend__(Gt):
- def call(self, ctx = None):
+class __extend__(Or):
+ def call(self, ctx):
+ s2 = self.left.call(ctx).GetValue()
+ if s2.ToBoolean():
+ return s2
+ s4 = self.right.call(ctx).GetValue()
+ return s4
+
+class __extend__(And):
+ def call(self, ctx):
s2 = self.left.call(ctx).GetValue()
+ if not s2.ToBoolean():
+ return s2
s4 = self.right.call(ctx).GetValue()
- s5 = ARC(s4, s2)
+ return s4
+
+
+class __extend__(BinaryOperator):
+ def call(self, ctx):
+ s2 = self.left.call(ctx).GetValue()
+ s4 = self.right.call(ctx).GetValue()
+ return self.decision(s2, s4)
+
+class __extend__(Ge):
+ def decision(self, op1, op2):
+ s5 = ARC(op1, op2)
+ if s5 is None or s5:
+ return W_Boolean(False)
+ else:
+ return W_Boolean(True)
+
+class __extend__(Gt):
+ def decision(self, op1, op2):
+ s5 = ARC(op2, op1)
if s5 is None:
return W_Boolean(False)
else:
return W_Boolean(s5)
+class __extend__(Le):
+ def decision(self, op1, op2):
+ s5 = ARC(op2, op1)
+ if s5 is None or s5:
+ return W_Boolean(False)
+ else:
+ return W_Boolean(True)
+
class __extend__(Lt):
- def call(self, ctx = None):
- s2 = self.left.call(ctx).GetValue()
- s4 = self.right.call(ctx).GetValue()
- s5 = ARC(s2, s4)
- print "< ARC result = ", s5
+ def decision(self, op1, op2):
+ s5 = ARC(op1, op2)
if s5 is None:
return W_Boolean(False)
else:
return W_Boolean(s5)
+def AEC(x, y):
+ """
+ Implements the Abstract Equality Comparison x == y
+ not following the specs yet
+ """
+ r = x.ToNumber() == y.ToNumber()
+ return r
+
+class __extend__(Eq):
+ def decision(self, op1, op2):
+ return W_Boolean(AEC(op1, op2))
+
+class __extend__(Ne):
+ def decision(self, op1, op2):
+ return W_Boolean(not AEC(op1, op2))
+
+
+class __extend__(In):
+ def decision(self, op1, op2):
+ if not isinstance(op2, W_Object):
+ raise ThrowException("TypeError")
+ name = op1.ToString()
+ return W_Boolean(op2.HasProperty(name))
+
+
class __extend__(Index):
- def call(self, ctx=None):
+ def call(self, ctx):
w_obj = self.left.call(ctx).GetValue()
w_member = self.expr.call(ctx).GetValue()
w_obj = w_obj.ToObject()
@@ -158,6 +217,12 @@
print "nodes = ", self.nodes
return [node.call(ctx) for node in self.nodes]
+class __extend__(Minus):
+ def decision(self, op1, op2):
+ x = op1.ToNumber()
+ y = op2.ToNumber()
+ return W_Number(x - y)
+
class __extend__(New):
def call(self, ctx=None):
obj = W_Object()
@@ -165,10 +230,8 @@
constructor = ctx.resolve_identifier(self.identifier).GetValue()
obj.Put('prototype', constructor.Get('prototype'))
constructor.Call(ctx, this = obj)
-
return obj
-
class __extend__(Number):
def call(self, ctx):
return W_Number(self.num)
@@ -188,13 +251,9 @@
return w_obj
class __extend__(Plus):
- def call(self, ctx):
- print "left", self.left.call(ctx)
- left = self.left.call(ctx).GetValue()
- right = self.right.call(ctx).GetValue()
- prim_left = left.ToPrimitive('Number')
- prim_right = right.ToPrimitive('Number')
- # INSANE
+ def decision(self, op1, op2):
+ prim_left = op1.ToPrimitive('Number')
+ prim_right = op2.ToPrimitive('Number')
if isinstance(prim_left, W_String) or isinstance(prim_right, W_String):
str_left = prim_left.ToString()
str_right = prim_right.ToString()
@@ -202,7 +261,6 @@
else:
num_left = prim_left.ToNumber()
num_right = prim_right.ToNumber()
- # XXX: obey all the rules
return W_Number(num_left + num_right)
class __extend__(Script):
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Tue Jan 2 22:03:29 2007
@@ -52,6 +52,9 @@
self.assert_prints("x=3;print(x);", ["3"])
self.assert_prints("x=3;y=4;print(x+y);", ["7"])
+ def test_minus(self):
+ self.assert_prints("print(2-1)", ["1"])
+
def test_string_var(self):
self.assert_prints('print(\"sss\");', ["sss"])
@@ -82,7 +85,6 @@
self.assert_prints('var x = 3; print(x);', ["3"])
self.assert_prints('var x = 3; print(x+x);', ["6"])
-
def test_var_scoping(self):
self.assert_prints("""
var y;
@@ -213,8 +215,22 @@
self.assert_prints("print(1<0)",["false"])
self.assert_prints("print(0<1)",["true"])
self.assert_prints("print(0<0)",["false"])
-
-
+ self.assert_prints("print(1>=0)",["true"])
+ self.assert_prints("print(1>=1)",["true"])
+ self.assert_prints("print(1>=2)",["false"])
+ self.assert_prints("print(0<=1)",["true"])
+ self.assert_prints("print(1<=1)",["true"])
+ self.assert_prints("print(1<=0)",["false"])
+ self.assert_prints("print(0==0)",["true"])
+ self.assert_prints("print(1==1)",["true"])
+ self.assert_prints("print(0==1)",["false"])
+ self.assert_prints("print(0!=1)",["true"])
+ self.assert_prints("print(1!=1)",["false"])
+
+ def test_binary_op(self):
+ self.assert_prints("print(0||0); print(1||0)",["0", "1"])
+ self.assert_prints("print(0&&1); print(1&&1)",["0", "1"])
+
def test_while(self):
self.assert_prints("""
i = 0;
@@ -262,13 +278,13 @@
def test_vars(self):
self.assert_prints("""
var x;x=3; print(x)""", ["3"])
-
- def test_fun_decl(self):
- py.test.skip("still not ready")
+
+ def test_minus(self):
self.assert_prints("""
- function x () { print('i work')}
- x()
- """, ["i work"])
+ x = {y:3};
+ print("y" in x);
+ print("z" in x);
+ """, ["true", "false"])
-
+
From arigo at codespeak.net Wed Jan 3 10:20:47 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 3 Jan 2007 10:20:47 +0100 (CET)
Subject: [pypy-svn] r36115 - pypy/dist/pypy/rpython
Message-ID: <20070103092047.76A8010064@code0.codespeak.net>
Author: arigo
Date: Wed Jan 3 10:20:44 2007
New Revision: 36115
Modified:
pypy/dist/pypy/rpython/llinterp.py
Log:
Python 2.3 compatibility.
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Wed Jan 3 10:20:44 2007
@@ -1,5 +1,6 @@
from pypy.objspace.flow.model import FunctionGraph, Constant, Variable, c_last_exception
-from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong, r_ulonglong
+from pypy.rlib.rarithmetic import intmask, r_uint, ovfcheck, r_longlong
+from pypy.rlib.rarithmetic import r_ulonglong, ovfcheck_lshift
from pypy.rpython.lltypesystem import lltype, llmemory, lloperation, llheap
from pypy.rpython.lltypesystem import rclass
from pypy.rpython.ootypesystem import ootype
@@ -786,6 +787,22 @@
except OverflowError:
self.make_llexception()
+ def op_int_lshift_ovf(self, x, y):
+ assert isinstance(x, int)
+ assert isinstance(y, int)
+ try:
+ return ovfcheck_lshift(x, y)
+ except OverflowError:
+ self.make_llexception()
+
+ def op_int_lshift_ovf_val(self, x, y):
+ assert isinstance(x, int)
+ assert isinstance(y, int)
+ try:
+ return ovfcheck_lshift(x, y)
+ except (OverflowError, ValueError):
+ self.make_llexception()
+
def _makefunc2(fn, operator, xtype, ytype=None):
import sys
d = sys._getframe(1).f_locals
@@ -816,9 +833,7 @@
_makefunc2('op_int_mod_ovf', '%', 'int')
_makefunc2('op_int_mod_zer', '%', 'int')
_makefunc2('op_int_mod_ovf_zer', '%', 'int')
- _makefunc2('op_int_lshift_ovf', '<<', 'int')
_makefunc2('op_int_lshift_val', '<<', 'int')
- _makefunc2('op_int_lshift_ovf_val', '<<', 'int')
_makefunc2('op_int_rshift_val', '>>', 'int')
_makefunc2('op_uint_floordiv_zer', '//', 'r_uint')
From mwh at codespeak.net Wed Jan 3 12:53:03 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Wed, 3 Jan 2007 12:53:03 +0100 (CET)
Subject: [pypy-svn] r36117 - in pypy/dist/pypy: config objspace/std
objspace/std/test
Message-ID: <20070103115303.E6F901006F@code0.codespeak.net>
Author: mwh
Date: Wed Jan 3 12:52:58 2007
New Revision: 36117
Modified:
pypy/dist/pypy/config/pypyoption.py
pypy/dist/pypy/objspace/std/objspace.py
pypy/dist/pypy/objspace/std/test/test_intobject.py
Log:
add a hopefully short-lived config option to specialize the addition of two
integers in BINARY_ADD like CPython does.
hopefully short-lived because it would be much nicer to specialize multimethod
implementations automagically...
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Wed Jan 3 12:52:58 2007
@@ -118,6 +118,10 @@
"list is mutaged",
default=False),
+ BoolOption("optimized_int_add",
+ "special case the addition of two integers in BINARY_ADD",
+ default=False),
+
BoolOption("oldstyle",
"specify whether the default metaclass should be classobj",
default=False, cmdline="--oldstyle"),
@@ -133,6 +137,7 @@
("objspace.std.withstrslice", True),
("objspace.std.withsmallint", True),
("objspace.std.withrangelist", True),
+ ("objspace.std.optimized_int_add", True),
],
cmdline="--faassen"),
Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py (original)
+++ pypy/dist/pypy/objspace/std/objspace.py Wed Jan 3 12:52:58 2007
@@ -2,6 +2,7 @@
from pypy.interpreter.baseobjspace import ObjSpace, Wrappable
from pypy.interpreter.error import OperationError, debug_print
from pypy.interpreter.typedef import get_unique_interplevel_subclass
+from pypy.interpreter import pyframe
from pypy.rlib.objectmodel import instantiate
from pypy.interpreter.gateway import PyPyCacheDir
from pypy.tool.cache import Cache
@@ -36,39 +37,6 @@
assert issubclass(implcls, W_Object)
_registered_implementations[implcls] = True
-from pypy.interpreter import pyframe
-
-class StdObjSpaceFrame(pyframe.PyFrame):
- def CALL_LIKELY_BUILTIN(f, oparg, *ignored):
- from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module
- from pypy.objspace.std.dictmultiobject import W_DictMultiObject
- w_globals = f.w_globals
- num = oparg >> 8
- assert isinstance(w_globals, W_DictMultiObject)
- w_value = w_globals.implementation.get_builtin_indexed(num)
- if w_value is None:
- w_builtins = f.builtin
- assert isinstance(w_builtins, Module)
- w_builtin_dict = w_builtins.w_dict
- assert isinstance(w_builtin_dict, W_DictMultiObject)
- w_value = w_builtin_dict.implementation.get_builtin_indexed(num)
-## if w_value is not None:
-## print "CALL_LIKELY_BUILTIN fast"
- if w_value is None:
- varname = OPTIMIZED_BUILTINS[num]
- message = "global name '%s' is not defined" % varname
- raise OperationError(f.space.w_NameError,
- f.space.wrap(message))
- nargs = oparg & 0xff
- w_function = w_value
- try:
- w_result = f.space.call_valuestack(w_function, nargs, f.valuestack)
- # XXX XXX fix the problem of resume points!
- #rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result)
- finally:
- f.valuestack.drop(nargs)
- f.valuestack.push(w_result)
-
##################################################################
class StdObjSpace(ObjSpace, DescrOperation):
@@ -88,6 +56,55 @@
# Import all the object types and implementations
self.model = StdTypeModel(self.config)
+ class StdObjSpaceFrame(pyframe.PyFrame):
+ if self.config.objspace.std.optimized_int_add:
+ def BINARY_ADD(f, oparg, *ignored):
+ from pypy.objspace.std.intobject import \
+ W_IntObject, add__Int_Int
+ w_2 = f.valuestack.pop()
+ w_1 = f.valuestack.pop()
+ if isinstance(w_1, W_IntObject) and \
+ isinstance(w_2, W_IntObject):
+ try:
+ w_result = add__Int_Int(f.space, w_1, w_2)
+ except FailedToImplement:
+ w_result = f.space.add(w_1, w_2)
+ else:
+ w_result = f.space.add(w_1, w_2)
+ f.valuestack.push(w_result)
+
+ def CALL_LIKELY_BUILTIN(f, oparg, *ignored):
+ from pypy.module.__builtin__ import OPTIMIZED_BUILTINS, Module
+ from pypy.objspace.std.dictmultiobject import W_DictMultiObject
+ w_globals = f.w_globals
+ num = oparg >> 8
+ assert isinstance(w_globals, W_DictMultiObject)
+ w_value = w_globals.implementation.get_builtin_indexed(num)
+ if w_value is None:
+ w_builtins = f.builtin
+ assert isinstance(w_builtins, Module)
+ w_builtin_dict = w_builtins.w_dict
+ assert isinstance(w_builtin_dict, W_DictMultiObject)
+ w_value = w_builtin_dict.implementation.get_builtin_indexed(num)
+ ## if w_value is not None:
+ ## print "CALL_LIKELY_BUILTIN fast"
+ if w_value is None:
+ varname = OPTIMIZED_BUILTINS[num]
+ message = "global name '%s' is not defined" % varname
+ raise OperationError(f.space.w_NameError,
+ f.space.wrap(message))
+ nargs = oparg & 0xff
+ w_function = w_value
+ try:
+ w_result = f.space.call_valuestack(w_function, nargs, f.valuestack)
+ # XXX XXX fix the problem of resume points!
+ #rstack.resume_point("CALL_FUNCTION", f, nargs, returns=w_result)
+ finally:
+ f.valuestack.drop(nargs)
+ f.valuestack.push(w_result)
+
+ self.FrameClass = StdObjSpaceFrame
+
# XXX store the dict class on the space to access it in various places
if self.config.objspace.std.withstrdict:
from pypy.objspace.std import dictstrobject
@@ -265,7 +282,7 @@
if not we_are_translated() and isinstance(code, CPythonFakeCode):
return CPythonFakeFrame(self, code, w_globals)
else:
- return StdObjSpaceFrame(self, code, w_globals, closure)
+ return self.FrameClass(self, code, w_globals, closure)
def gettypefor(self, cls):
return self.gettypeobject(cls.typedef)
Modified: pypy/dist/pypy/objspace/std/test/test_intobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_intobject.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_intobject.py Wed Jan 3 12:52:58 2007
@@ -375,3 +375,8 @@
def test_getnewargs(self):
assert 0 .__getnewargs__() == (0,)
+
+class AppTestIntOptimizedAdd(AppTestInt):
+ def setup_class(cls):
+ from pypy.conftest import gettestobjspace
+ cls.space = gettestobjspace(**{"objspace.std.optimized_int_add": True})
From afayolle at codespeak.net Wed Jan 3 14:04:57 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Wed, 3 Jan 2007 14:04:57 +0100 (CET)
Subject: [pypy-svn] r36118 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070103130457.3AF5010069@code0.codespeak.net>
Author: afayolle
Date: Wed Jan 3 14:04:55 2007
New Revision: 36118
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/people.txt
Log:
Woops, I had forgotten to check this in
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/people.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/people.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/people.txt Wed Jan 3 14:04:55 2007
@@ -27,6 +27,8 @@
Carl Friedrich Bolz 5th-14th Ermina
Guido Wesdorp 6th-14th Ermina
Leonardo Santagada 6th-14th Ermina
+Alexandre Fayolle 8th-12th Ermina
+Sylvain Th?nault 8th-12th Ermina
==================== ============== =====================
People on the following list were present at previous sprints:
@@ -38,8 +40,6 @@
Michael Hudson ? ?
Anders Lehmann ? ?
Niklaus Haldimann ? ?
-Aurelien Campeas ? ?
-Alexandre Fayolle ? ?
Lene Wagner ? ?
Amaury Forgeot d'Arc ? ?
Valentino Volonghi ? ?
From arigo at codespeak.net Wed Jan 3 16:16:45 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 3 Jan 2007 16:16:45 +0100 (CET)
Subject: [pypy-svn] r36119 - pypy/dist/pypy/rpython/memory
Message-ID: <20070103151645.25AB110068@code0.codespeak.net>
Author: arigo
Date: Wed Jan 3 16:16:43 2007
New Revision: 36119
Modified:
pypy/dist/pypy/rpython/memory/gc.py
Log:
Fix a complete bug in x_become(): replace the old object with the new one
*before* we follow a pointer... otherwise the new object can be freed!
Modified: pypy/dist/pypy/rpython/memory/gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc.py (original)
+++ pypy/dist/pypy/rpython/memory/gc.py Wed Jan 3 16:16:43 2007
@@ -530,7 +530,8 @@
item = obj + itemlength * i
j = 0
while j < len(offsets):
- objects.append((item + offsets[j]).address[0])
+ pointer = item + offsets[j]
+ objects.append(pointer.address[0])
j += 1
i += 1
@@ -733,13 +734,13 @@
i = 0
while i < len(offsets):
pointer = obj + offsets[i]
- objects.append(pointer.address[0])
# -------------------------------------------------
# begin difference from collect
if pointer.address[0] == target_addr:
pointer.address[0] = source_addr
# end difference from collect
# -------------------------------------------------
+ objects.append(pointer.address[0])
i += 1
if self.is_varsize(typeid):
offset = self.varsize_offset_to_variable_part(
@@ -753,14 +754,14 @@
item = obj + itemlength * i
j = 0
while j < len(offsets):
- objects.append((item + offsets[j]).address[0])
+ pointer = item + offsets[j]
# -------------------------------------------------
# begin difference from collect
- pointer = item + offsets[j]
if pointer.address[0] == target_addr:
pointer.address[0] = source_addr
## end difference from collect
# -------------------------------------------------
+ objects.append(pointer.address[0])
j += 1
i += 1
From arigo at codespeak.net Wed Jan 3 16:26:44 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 3 Jan 2007 16:26:44 +0100 (CET)
Subject: [pypy-svn] r36120 - in pypy/dist/pypy: rlib/rctypes
rlib/rctypes/test rpython rpython/lltypesystem
rpython/lltypesystem/test rpython/memory
rpython/memory/gctransform rpython/memory/gctransform/test
translator/c translator/llvm
Message-ID: <20070103152644.0DAA610068@code0.codespeak.net>
Author: arigo
Date: Wed Jan 3 16:26:37 2007
New Revision: 36120
Modified:
pypy/dist/pypy/rlib/rctypes/rctypesobject.py
pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/lltypesystem/llmemory.py
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
pypy/dist/pypy/rpython/memory/gcheader.py
pypy/dist/pypy/rpython/memory/gctransform/framework.py
pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py
pypy/dist/pypy/translator/c/database.py
pypy/dist/pypy/translator/c/primitive.py
pypy/dist/pypy/translator/llvm/database.py
Log:
Simplification of llmemory, triggered by the fact that two addresses
would compare as different if they were obtained in different ways,
even if they pointed to the same final object.
The 'offset' field of fakeaddress is gone, and 'ob' is renamed to 'ptr'.
It's always just a pointer. With the new stuff in lltype like
direct_fieldptr() we can take pointers to fields, or array items, so no
need for anything more.
Hack a bit for arenas and address-of-length-of-array.
A new test in rctypesobject that triggered this whole thing,
and implementation of recursive data structures.
llvm/database.py updated but not tested (will do so on another machine).
gctransform/test/test_framework took ages because of the llinterpretation
of a raw_memclear() of the root stack, with 160'000 items!
Trying to do something cleaner about raw_memcopy() in llmemory.py.
Modified: pypy/dist/pypy/rlib/rctypes/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rctypesobject.py Wed Jan 3 16:26:37 2007
@@ -242,35 +242,29 @@
try:
return contentscls._ptrcls
except AttributeError:
- assert issubclass(contentscls, RCTypesObject)
- if contentscls in _abstract_classes:
- raise Exception("cannot call RPointer(%s) or "
- "pointer(x) if x degenerated to the base "
- "%s class" % (contentscls.__name__,
- contentscls.__name__,))
class RCTypesPtr(RCTypesObject):
- CONTENTS = contentscls.CDATATYPE
- LLTYPE = lltype.Ptr(CONTENTS)
+ LLTYPE = lltype.Ptr(lltype.ForwardReference())
num_keepalives = 1
+ setpointertype = classmethod(_rpointer_set_pointer_type)
def get_contents(self):
ptr = self.ll_ref(RCTypesPtr.CDATATYPE)
targetaddr = llmemory.cast_ptr_to_adr(ptr[0])
keepalive_until_here(self)
- targetkeepalives = contentscls.num_keepalives
+ targetkeepalives = RCTypesPtr.CONTENTSCLS.num_keepalives
targetmemblock = self._getmemblock(0, targetkeepalives)
- return contentscls(targetaddr, targetmemblock)
+ return RCTypesPtr.CONTENTSCLS(targetaddr, targetmemblock)
def ref(self, index):
ptr = self.ll_ref(RCTypesPtr.CDATATYPE)
targetaddr = llmemory.cast_ptr_to_adr(ptr[0])
if index:
- targetaddr += ofs_item * index
+ targetaddr += self._OFS_ITEM * index
keepalive_until_here(self)
- targetkeepalives = contentscls.num_keepalives
+ targetkeepalives = RCTypesPtr.CONTENTSCLS.num_keepalives
targetmemblock = self._getmemblock(0, targetkeepalives)
- return contentscls(targetaddr, targetmemblock)
+ return RCTypesPtr.CONTENTSCLS(targetaddr, targetmemblock)
def set_contents(self, newcontentsbox):
targetaddr = newcontentsbox.addr
@@ -293,11 +287,30 @@
keepalive_until_here(self)
self._keepalivememblock(0, None)
- ofs_item = llmemory.sizeof(contentscls.LLTYPE)
- contentscls._ptrcls = RCTypesPtr
+ if contentscls is None:
+ pass # forward pointer
+ else:
+ RCTypesPtr.setpointertype(contentscls)
return RCTypesPtr
RPointer._annspecialcase_ = 'specialize:memo'
+def _rpointer_set_pointer_type(RCTypesPtr, contentscls):
+ assert issubclass(contentscls, RCTypesObject)
+ if contentscls in _abstract_classes:
+ raise Exception("cannot call RPointer(%s) or "
+ "pointer(x) if x degenerated to the base "
+ "%s class" % (contentscls.__name__,
+ contentscls.__name__,))
+ RCTypesPtr.CONTENTSCLS = contentscls
+ RCTypesPtr.CONTENTS = contentscls.CDATATYPE
+ RCTypesPtr.LLTYPE.TO.become(RCTypesPtr.CONTENTS)
+ RCTypesPtr._OFS_ITEM = llmemory.sizeof(contentscls.LLTYPE)
+ RCTypesPtr.__name__ = 'RCTypes_%s' % (RCTypesPtr.LLTYPE,)
+ assert not hasattr(contentscls, '_ptrcls'), (
+ "the RPointer class corresponding to %r exists already" %
+ (contentscls,))
+ contentscls._ptrcls = RCTypesPtr
+
def pointer(x):
PTR = RPointer(x.__class__)
p = PTR.allocate()
Modified: pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rctypesobject.py Wed Jan 3 16:26:37 2007
@@ -266,6 +266,18 @@
res = self.do(func)
assert res == 101
+ def test_recursive_structure(self):
+ P1 = RPointer(None)
+ S1 = RStruct('S1', [('next', P1)])
+ P1.setpointertype(S1)
+ def func():
+ s1 = S1.allocate()
+ s2 = S1.allocate()
+ s2.ref_next().set_contents(s1)
+ return s2.ref_next().get_contents().sameaddr(s1)
+ res = self.do(func)
+ assert res == True
+
POLICY = AnnotatorPolicy()
POLICY.allow_someobjects = False
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Wed Jan 3 16:26:37 2007
@@ -571,8 +571,7 @@
def op_unsafe_call(self, TGT, f):
checkadr(f)
- assert f.offset is None
- obj = self.llinterpreter.typer.type_system.deref(f.ob)
+ obj = self.llinterpreter.typer.type_system.deref(f.ref())
assert hasattr(obj, 'graph') # don't want to think about that
graph = obj.graph
args = []
@@ -670,8 +669,8 @@
def op_gc_call_rtti_destructor(self, rtti, addr):
if hasattr(rtti._obj, 'destructor_funcptr'):
d = rtti._obj.destructor_funcptr
- ob = addr.get()
- return self.op_direct_call(d, ob)
+ obptr = addr.ref()
+ return self.op_direct_call(d, obptr)
def op_gc_deallocate(self, TYPE, addr):
raise NotImplementedError("gc_deallocate")
Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Wed Jan 3 16:26:37 2007
@@ -4,6 +4,7 @@
# sizeof, offsetof
+import weakref
from pypy.rlib.objectmodel import Symbolic
from pypy.rpython.lltypesystem import lltype
@@ -21,11 +22,12 @@
return NotImplemented
return CompositeOffset(self, other)
- def raw_malloc(self, rest):
+ def raw_malloc(self, rest, zero):
raise NotImplementedError("raw_malloc(%r, %r)" % (self, rest))
- def raw_memclear(self, adr):
- raise NotImplementedError("raw_memclear(%r, %r)" % (self, adr))
+ def raw_memcopy(self, srcadr, dstsrc):
+ raise NotImplementedError("raw_memcopy(%r)" % (self,))
+
class ItemOffset(AddressOffset):
@@ -46,56 +48,57 @@
def __neg__(self):
return ItemOffset(self.TYPE, -self.repeat)
- def ref(self, firstitemref):
- if isinstance(firstitemref, _obref):
- parent, index = lltype.parentlink(firstitemref.ob._obj)
- if parent is None:
- raise TypeError("address + itemoffset: not the address"
- " of an array")
- A = lltype.typeOf(parent)
- assert isinstance(A, (lltype.Array, lltype.FixedSizeArray))
+ def ref(self, firstitemptr):
+ A = lltype.typeOf(firstitemptr).TO
+ if A == self.TYPE:
+ # for array of containers
+ parent, index = lltype.parentlink(firstitemptr._obj)
+ assert parent, "%r is not within a container" % (firstitemptr,)
+ assert isinstance(lltype.typeOf(parent),
+ (lltype.Array, lltype.FixedSizeArray)), (
+ "%r is not within an array" % (firstitemptr,))
if isinstance(index, str):
- assert index.startswith("item")
- index = int(index[4:]) # "itemN" => N
- firstitemref = _arrayitemref(parent._as_ptr(), index)
- assert isinstance(firstitemref, _arrayitemref)
- array = firstitemref.array
- assert lltype.typeOf(array).TO.OF == self.TYPE
- index = firstitemref.index + self.repeat
- return _arrayitemref(array, index)
+ assert index.startswith('item') # itemN => N
+ index = int(index[4:])
+ return parent.getitem(index + self.repeat)._as_ptr()
+ elif isinstance(A, lltype.FixedSizeArray) and A.OF == self.TYPE:
+ # for array of primitives or pointers
+ return lltype.direct_ptradd(firstitemptr, self.repeat)
+ else:
+ raise TypeError('got %r, expected %r' % (A, self.TYPE))
- def raw_malloc(self, rest):
+ def raw_malloc(self, rest, zero):
assert not rest
if (isinstance(self.TYPE, lltype.ContainerType)
and self.TYPE._gckind == 'gc'):
assert self.repeat == 1
- p = lltype.malloc(self.TYPE, flavor='raw')
+ p = lltype.malloc(self.TYPE, flavor='raw', zero=zero)
return cast_ptr_to_adr(p)
else:
T = lltype.FixedSizeArray(self.TYPE, self.repeat)
- p = lltype.malloc(T, flavor='raw')
+ p = lltype.malloc(T, flavor='raw', zero=zero)
array_adr = cast_ptr_to_adr(p)
return array_adr + ArrayItemsOffset(T)
- def raw_memclear(self, adr):
- if (isinstance(self.TYPE, lltype.ContainerType) and self.repeat == 1):
- from pypy.rpython.rctypes.rmodel import reccopy
- fresh = lltype.malloc(self.TYPE, flavor='raw', zero=True)
- reccopy(fresh, adr.get())
- else:
- assert adr.offset is not None
- if isinstance(adr.offset, ArrayItemsOffset):
- array = adr.ob
- elif isinstance(adr.offset, CompositeOffset):
- array = (adr + -adr.offset.offsets[-1]).get()
- if isinstance(self.TYPE, lltype.ContainerType):
- fresh = lltype.malloc(self.TYPE, flavor='raw', zero=True)
- for i in range(self.repeat):
- reccopy(fresh, array[i])
- else:
- for i in range(self.repeat):
- array[i] = self.TYPE._defl()
-
+ def raw_memcopy(self, srcadr, dstadr):
+ repeat = self.repeat
+ if repeat == 0:
+ return
+ from pypy.rpython.rctypes.rmodel import reccopy
+ if isinstance(self.TYPE, lltype.ContainerType):
+ PTR = lltype.Ptr(self.TYPE)
+ else:
+ PTR = lltype.Ptr(lltype.FixedSizeArray(self.TYPE, 1))
+ while True:
+ src = cast_adr_to_ptr(srcadr, PTR)
+ dst = cast_adr_to_ptr(dstadr, PTR)
+ reccopy(src, dst)
+ repeat -= 1
+ if repeat <= 0:
+ break
+ srcadr += ItemOffset(self.TYPE)
+ dstadr += ItemOffset(self.TYPE)
+
class FieldOffset(AddressOffset):
@@ -106,33 +109,31 @@
def __repr__(self):
return "" % (self.TYPE, self.fldname)
- def ref(self, containerref):
- struct = containerref.get()
+ def ref(self, struct):
if lltype.typeOf(struct).TO != self.TYPE:
struct = lltype.cast_pointer(lltype.Ptr(self.TYPE), struct)
- return _structfieldref(struct, self.fldname)
+ FIELD = getattr(self.TYPE, self.fldname)
+ if isinstance(FIELD, lltype.ContainerType):
+ return getattr(struct, self.fldname)
+ else:
+ return lltype.direct_fieldptr(struct, self.fldname)
- def raw_malloc(self, rest, parenttype=None):
+ def raw_malloc(self, rest, parenttype=None, zero=False):
if self.fldname != self.TYPE._arrayfld:
- return AddressOffset.raw_malloc(self, rest) # for the error msg
+ # for the error msg
+ return AddressOffset.raw_malloc(self, rest, zero=zero)
assert rest
- return rest[0].raw_malloc(rest[1:], parenttype=parenttype or self.TYPE)
+ return rest[0].raw_malloc(rest[1:], parenttype=parenttype or self.TYPE,
+ zero=zero)
- def raw_memclear(self, adr):
+ def raw_memcopy(self, srcadr, dstadr):
if self.fldname != self.TYPE._arrayfld:
- return AddressOffset.raw_memclear(adr) # for the error msg
- structptr = adr.get()
- for name in self.TYPE._names[:-1]:
- FIELDTYPE = getattr(self.TYPE, name)
- if isinstance(FIELDTYPE, lltype.ContainerType):
- fresh = lltype.malloc(FIELDTYPE, raw=True, zero=True)
- from pypy.rpython.rctypes.rmodel import reccopy
- fresh = lltype.malloc(self.TYPE, flavor='raw', zero=True)
- reccopy(fresh, getattr(structptr, name)._obj)
- else:
- setattr(structptr, name, FIELDTYPE._defl())
-
-
+ return AddressOffset.raw_memcopy(srcadr, dstadr) #for the error msg
+ PTR = lltype.Ptr(self.TYPE)
+ src = cast_adr_to_ptr(srcadr, PTR)
+ dst = cast_adr_to_ptr(dstadr, PTR)
+ from pypy.rpython.rctypes.rmodel import reccopy
+ reccopy(src, dst)
class CompositeOffset(AddressOffset):
@@ -165,19 +166,21 @@
ofs.reverse()
return CompositeOffset(*ofs)
- def ref(self, ref):
+ def ref(self, ptr):
for item in self.offsets:
- ref = item.ref(ref)
- return ref
+ ptr = item.ref(ptr)
+ return ptr
- def raw_malloc(self, rest):
- return self.offsets[0].raw_malloc(self.offsets[1:] + rest)
+ def raw_malloc(self, rest, zero):
+ return self.offsets[0].raw_malloc(self.offsets[1:] + rest, zero=zero)
- def raw_memclear(self, adr):
+ def raw_memcopy(self, srcadr, dstadr):
for o in self.offsets[:-1]:
- o.raw_memclear(adr)
- adr += o
- o.raw_memclear(adr)
+ o.raw_memcopy(srcadr, dstadr)
+ srcadr += o
+ dstadr += o
+ o = self.offsets[-1]
+ o.raw_memcopy(srcadr, dstadr)
class ArrayItemsOffset(AddressOffset):
@@ -188,12 +191,14 @@
def __repr__(self):
return '< ArrayItemsOffset %r >' % (self.TYPE,)
- def ref(self, arrayref):
- array = arrayref.get()
- assert lltype.typeOf(array).TO == self.TYPE
- return _arrayitemref(array, index=0)
+ def ref(self, arrayptr):
+ assert lltype.typeOf(arrayptr).TO == self.TYPE
+ if isinstance(self.TYPE.OF, lltype.ContainerType):
+ return arrayptr[0]
+ else:
+ return lltype.direct_arrayitems(arrayptr)
- def raw_malloc(self, rest, parenttype=None):
+ def raw_malloc(self, rest, parenttype=None, zero=False):
if rest:
assert len(rest) == 1
assert isinstance(rest[0], ItemOffset)
@@ -204,11 +209,12 @@
if self.TYPE._hints.get('isrpystring'):
count -= 1 # because malloc() will give us the extra char for free
p = lltype.malloc(parenttype or self.TYPE, count,
- immortal = self.TYPE._gckind == 'raw')
+ immortal = self.TYPE._gckind == 'raw',
+ zero = zero)
return cast_ptr_to_adr(p)
- def raw_memclear(self, adr):
- # should really zero out the length field, but we can't
+ def raw_memcopy(self, srcadr, dstadr):
+ # should really copy the length field, but we can't
pass
@@ -220,10 +226,9 @@
def __repr__(self):
return '< ArrayLengthOffset %r >' % (self.TYPE,)
- def ref(self, arrayref):
- array = arrayref.get()
- assert lltype.typeOf(array).TO == self.TYPE
- return _arraylenref(array)
+ def ref(self, arrayptr):
+ assert lltype.typeOf(arrayptr).TO == self.TYPE
+ return lltype._arraylenref._makeptr(arrayptr._obj, arrayptr._solid)
class GCHeaderOffset(AddressOffset):
@@ -236,22 +241,21 @@
def __neg__(self):
return GCHeaderAntiOffset(self.gcheaderbuilder)
- def ref(self, headerref):
- header = headerref.get()
- gcptr = self.gcheaderbuilder.object_from_header(header)
- return _obref(gcptr)
+ def ref(self, headerptr):
+ gcptr = self.gcheaderbuilder.object_from_header(headerptr)
+ return gcptr
- def raw_malloc(self, rest):
+ def raw_malloc(self, rest, zero):
assert rest
if isinstance(rest[0], GCHeaderAntiOffset):
- return rest[1].raw_malloc(rest[2:]) # just for fun
- gcobjadr = rest[0].raw_malloc(rest[1:])
- headerptr = self.gcheaderbuilder.new_header(gcobjadr.get())
+ return rest[1].raw_malloc(rest[2:], zero=zero) # just for fun
+ gcobjadr = rest[0].raw_malloc(rest[1:], zero=zero)
+ headerptr = self.gcheaderbuilder.new_header(gcobjadr.ptr)
return cast_ptr_to_adr(headerptr)
- def raw_memclear(self, adr):
- headerptr = adr.get()
- sizeof(lltype.typeOf(headerptr).TO).raw_memclear(cast_ptr_to_adr(headerptr))
+ def raw_memcopy(self, srcadr, dstadr):
+ from pypy.rpython.rctypes.rmodel import reccopy
+ reccopy(srcadr.ptr, dstadr.ptr)
class GCHeaderAntiOffset(AddressOffset):
def __init__(self, gcheaderbuilder):
@@ -263,85 +267,14 @@
def __neg__(self):
return GCHeaderOffset(self.gcheaderbuilder)
- def ref(self, gcptrref):
- gcptr = gcptrref.get()
+ def ref(self, gcptr):
headerptr = self.gcheaderbuilder.header_of_object(gcptr)
- return _obref(headerptr)
+ return headerptr
- def raw_malloc(self, rest):
+ def raw_malloc(self, rest, zero):
assert len(rest) >= 2
assert isinstance(rest[0], GCHeaderOffset)
- return rest[1].raw_malloc(rest[2:])
-
-
-class _arrayitemref(object):
- def __init__(self, array, index):
- self.array = array
- self.index = index
- def get(self):
- return self.array[self.index]
- def set(self, value):
- self.array[self.index] = value
- def __eq__(self, other):
- if self.__class__ is not other.__class__:
- return False
- return self.array._same_obj(other.array) and \
- self.index == other.index
- def __ne__(self, other):
- return not (self == other)
- def type(self):
- return lltype.typeOf(self.array).TO.OF
-
-class _arraylenref(object):
- def __init__(self, array):
- self.array = array
- def get(self):
- return len(self.array)
- def set(self, value):
- if value != len(self.array):
- raise Exception("can't change the length of an array")
- def __eq__(self, other):
- if self.__class__ is not other.__class__:
- return False
- return self.array._same_obj(other.array)
- def __ne__(self, other):
- return not (self == other)
- def type(self):
- return lltype.Signed
-
-class _structfieldref(object):
- def __init__(self, struct, fieldname):
- self.struct = struct
- self.fieldname = fieldname
- def get(self):
- return getattr(self.struct, self.fieldname)
- def set(self, value):
- setattr(self.struct, self.fieldname, value)
- def __eq__(self, other):
- if self.__class__ is not other.__class__:
- return False
- return self.struct._same_obj(other.struct) and \
- self.fieldname == other.fieldname
- def __ne__(self, other):
- return not (self == other)
- def type(self):
- return getattr(lltype.typeOf(self.struct).TO, self.fieldname)
-
-class _obref(object):
- def __init__(self, ob):
- self.ob = ob
- def get(self):
- return self.ob
- def set(self, value):
- raise Exception("can't assign to whole object")
- def __eq__(self, other):
- if self.__class__ is not other.__class__:
- return False
- return self.ob._same_obj(other.ob)
- def __ne__(self, other):
- return not (self == other)
- def type(self):
- return lltype.typeOf(self.ob)
+ return rest[1].raw_malloc(rest[2:], zero=zero)
# ____________________________________________________________
@@ -367,30 +300,23 @@
# -------------------------------------------------------------
class fakeaddress(object):
- # NOTE: the 'ob' in the addresses must be normalized.
+ # NOTE: the 'ptr' in the addresses must be normalized.
# Use cast_ptr_to_adr() instead of directly fakeaddress() if unsure.
- def __init__(self, ob, offset=None):
- self.ob = ob
- self.offset = offset
+ def __init__(self, ptr):
+ self.ptr = ptr or None # null ptr => None
def __repr__(self):
- if self.ob is None:
+ if self.ptr is None:
s = 'NULL'
else:
- s = str(self.ob)
- if self.offset is not None:
- s = '%s + %r' % (s, self.offset)
+ s = str(self.ptr)
return '' % (s,)
def __add__(self, other):
if isinstance(other, AddressOffset):
- if self.offset is None:
- offset = other
- else:
- offset = self.offset + other
- res = fakeaddress(self.ob, offset)
- res.ref() # sanity check
- return res
+ if self.ptr is None:
+ raise NullAddressError("offset from NULL address")
+ return fakeaddress(other.ref(self.ptr))
if other == 0:
return self
return NotImplemented
@@ -403,62 +329,71 @@
return NotImplemented
def __nonzero__(self):
- return self.ob is not None
+ return self.ptr is not None
def __eq__(self, other):
- if not isinstance(other, fakeaddress):
- return False
- if self.ob is None:
- return other.ob is None
- if other.ob is None:
- return False
- return self.ref() == other.ref()
+ if isinstance(other, fakeaddress):
+ obj1 = self.ptr
+ obj2 = other.ptr
+ if obj1 is not None: obj1 = obj1._obj
+ if obj2 is not None: obj2 = obj2._obj
+ return obj1 == obj2
+ else:
+ return NotImplemented
def __ne__(self, other):
- return not (self == other)
+ if isinstance(other, fakeaddress):
+ return not (self == other)
+ else:
+ return NotImplemented
def ref(self):
if not self:
raise NullAddressError
- ref = _obref(self.ob)
- if self.offset is not None:
- ref = self.offset.ref(ref)
- return ref
+ return self.ptr
- def get(self):
- return self.ref().get()
+## def get(self):
+## return self.ref().get()
- def set(self, value):
- self.ref().set(value)
+## def set(self, value):
+## self.ref().set(value)
def _cast_to_ptr(self, EXPECTED_TYPE):
- if not self:
- return lltype.nullptr(EXPECTED_TYPE.TO)
- ref = self.ref()
- if (isinstance(ref, _arrayitemref) and
- isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and
- ref.type() == EXPECTED_TYPE.TO.OF):
- # special case that requires direct_arrayitems
- p_items = lltype.direct_arrayitems(ref.array)
- return lltype.direct_ptradd(p_items, ref.index)
- elif (isinstance(ref, _structfieldref) and
- isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and
- ref.type() == EXPECTED_TYPE.TO.OF):
- # special case that requires direct_fieldptr
- return lltype.direct_fieldptr(ref.struct,
- ref.fieldname)
- else:
- result = ref.get()
+ if self:
+ PTRTYPE = lltype.typeOf(self.ptr)
if (isinstance(EXPECTED_TYPE.TO, lltype.OpaqueType) or
- isinstance(lltype.typeOf(result).TO, lltype.OpaqueType)):
- return lltype.cast_opaque_ptr(EXPECTED_TYPE, result)
+ isinstance(PTRTYPE.TO, lltype.OpaqueType)):
+ return lltype.cast_opaque_ptr(EXPECTED_TYPE, self.ptr)
else:
# regular case
- return lltype.cast_pointer(EXPECTED_TYPE, result)
+ return lltype.cast_pointer(EXPECTED_TYPE, self.ptr)
+ else:
+ return lltype.nullptr(EXPECTED_TYPE.TO)
+
+## if (isinstance(ref, _arrayitemref) and
+## isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and
+## ref.type() == EXPECTED_TYPE.TO.OF):
+## # special case that requires direct_arrayitems
+## p_items = lltype.direct_arrayitems(ref.array)
+## return lltype.direct_ptradd(p_items, ref.index)
+## elif (isinstance(ref, _structfieldref) and
+## isinstance(EXPECTED_TYPE.TO, lltype.FixedSizeArray) and
+## ref.type() == EXPECTED_TYPE.TO.OF):
+## # special case that requires direct_fieldptr
+## return lltype.direct_fieldptr(ref.struct,
+## ref.fieldname)
+## else:
+## result = ref.get()
+## if (isinstance(EXPECTED_TYPE.TO, lltype.OpaqueType) or
+## isinstance(lltype.typeOf(result).TO, lltype.OpaqueType)):
+## return lltype.cast_opaque_ptr(EXPECTED_TYPE, result)
+## else:
+## # regular case
+## return lltype.cast_pointer(EXPECTED_TYPE, result)
def _cast_to_int(self):
if self:
- return self.get()._cast_to_int()
+ return self.ptr._cast_to_int()
else:
return 0
@@ -482,25 +417,25 @@
def __init__(self, addr):
self.addr = addr
def __getitem__(self, index):
- addr = self.addr
+ ptr = self.addr.ref()
if index != 0:
- addr += ItemOffset(addr.ref().type(), index)
- return self.erase_type(addr.get())
+ ptr = lltype.direct_ptradd(ptr, index)
+ return self.read_from_ptr(ptr)
def __setitem__(self, index, value):
assert lltype.typeOf(value) == self.TYPE
- addr = self.addr
+ ptr = self.addr.ref()
if index != 0:
- addr += ItemOffset(addr.ref().type(), index)
- addr.set(self.unerase_type(addr.ref().type(), value))
+ ptr = lltype.direct_ptradd(ptr, index)
+ self.write_into_ptr(ptr, value)
- def erase_type(self, value):
+ def read_from_ptr(self, ptr):
+ value = ptr[0]
assert lltype.typeOf(value) == self.TYPE
return value
- def unerase_type(self, TARGETTYPE, value):
- assert lltype.typeOf(value) == TARGETTYPE
- return value
+ def write_into_ptr(self, ptr, value):
+ ptr[0] = value
class _signed_fakeaccessor(_fakeaccessor):
@@ -512,7 +447,8 @@
class _address_fakeaccessor(_fakeaccessor):
TYPE = Address
- def erase_type(self, value):
+ def read_from_ptr(self, ptr):
+ value = ptr[0]
if isinstance(value, lltype._ptr):
return value._cast_to_adr()
elif lltype.typeOf(value) == Address:
@@ -520,13 +456,15 @@
else:
raise TypeError(value)
- def unerase_type(self, TARGETTYPE, value):
+ def write_into_ptr(self, ptr, value):
+ TARGETTYPE = lltype.typeOf(ptr).TO.OF
if TARGETTYPE == Address:
- return value
+ pass
elif isinstance(TARGETTYPE, lltype.Ptr):
- return cast_adr_to_ptr(value, TARGETTYPE)
+ value = cast_adr_to_ptr(value, TARGETTYPE)
else:
- raise TypeError(TARGETTYPE, value)
+ raise TypeError(TARGETTYPE)
+ ptr[0] = value
fakeaddress.signed = property(_signed_fakeaccessor)
@@ -552,8 +490,6 @@
# ____________________________________________________________
-import weakref
-
class fakeweakaddress(object):
def __init__(self, ob):
if ob is not None:
@@ -607,12 +543,19 @@
def raw_malloc(size):
if not isinstance(size, AddressOffset):
raise NotImplementedError(size)
- return size.raw_malloc([])
+ return size.raw_malloc([], zero=False)
def raw_free(adr):
- # xxx crash if you get only the header of a gc object
- assert isinstance(adr.ob._obj, lltype._parentable)
- adr.ob._as_obj()._free()
+ # try to free the whole object if 'adr' is the address of the header
+ from pypy.rpython.memory.gcheader import GCHeaderBuilder
+ try:
+ objectptr = GCHeaderBuilder.object_from_header(adr.ptr)
+ except KeyError:
+ pass
+ else:
+ raw_free(cast_ptr_to_adr(objectptr))
+ assert isinstance(adr.ref()._obj, lltype._parentable)
+ adr.ptr._as_obj()._free()
def raw_malloc_usage(size):
if isinstance(size, AddressOffset):
@@ -625,58 +568,64 @@
if not isinstance(size, AddressOffset):
raise NotImplementedError(size)
assert lltype.typeOf(adr) == Address
- size.raw_memclear(adr)
+ zeroadr = size.raw_malloc([], zero=True)
+ size.raw_memcopy(zeroadr, adr)
def raw_memcopy(source, dest, size):
- source = source.get()
- dest = dest.get()
- # this check would be nice...
- #assert sizeof(lltype.typeOf(source)) == sizeof(lltype.typeOf(dest)) == size
- from pypy.rpython.rctypes.rmodel import reccopy
- reccopy(source, dest)
+ assert lltype.typeOf(source) == Address
+ assert lltype.typeOf(dest) == Address
+ size.raw_memcopy(source, dest)
# ____________________________________________________________
+ARENA_ITEM = lltype.OpaqueType('ArenaItem')
+
class _arena(object):
+ #_cache = weakref.WeakKeyDictionary() # {obj: _arenaitem}
- def __init__(self, rng):
+ def __init__(self, rng, zero):
self.rng = rng
+ self.zero = zero
self.items = []
-class ArenaItem(AddressOffset):
-
- def __init__(self, nr):
+ def getitemaddr(self, n):
+ while len(self.items) <= n:
+ self.items.append(_arenaitem(self, len(self.items)))
+ return fakeaddress(self.items[n]._as_ptr())
+
+class _arenaitem(lltype._container):
+ _TYPE = ARENA_ITEM
+
+ def __init__(self, arena, nr):
+ self.arena = arena
self.nr = nr
+ self.reserved_size = None
+
+ def reserve(self, size):
+ if self.reserved_size is None:
+ # xxx check that we are not larger than unitsize*n
+ itemadr = raw_malloc(size)
+ self.container = itemadr.ptr._obj
+ #_arena._cache[itemadr.ptr._obj] = self
+ else:
+ assert size == self.reserved_size
- def ref(self, ref):
- assert isinstance(ref, _obref)
- assert isinstance(ref.ob, _arena)
- arena = ref.ob
- itemadr = arena.items[self.nr]
- return itemadr.ref()
-
class ArenaRange(AddressOffset):
def __init__(self, unitsize, n):
self.unitsize = unitsize
self.n = n
- def raw_malloc(self, rest):
+ def raw_malloc(self, rest, zero=False):
assert not rest
- return fakeaddress(_arena(self), ArenaItem(0))
+ arena = _arena(self, zero=zero)
+ return arena.getitemaddr(0)
def arena(TYPE, n):
return ArenaRange(sizeof(TYPE), n)
def bump(adr, size):
- assert isinstance(adr.ob, _arena)
- assert isinstance(adr.offset, ArenaItem)
- arena = adr.ob
- nr = adr.offset.nr
- if len(arena.items) == nr: # reserve
- # xxx check that we are not larger than unitsize*n
- itemadr = raw_malloc(size)
- arena.items.append(itemadr)
- else:
- assert nr < len(arena.items)
- # xxx check that size matches
- return fakeaddress(arena, ArenaItem(nr+1))
+ baseptr = cast_adr_to_ptr(adr, lltype.Ptr(ARENA_ITEM))
+ baseptr._obj.reserve(size)
+ arena = baseptr._obj.arena
+ nr = baseptr._obj.nr
+ return arena.getitemaddr(nr + 1)
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Wed Jan 3 16:26:37 2007
@@ -759,6 +759,8 @@
CURTYPE = typeOf(ptr)
if not isinstance(CURTYPE, Ptr) or not isinstance(PTRTYPE, Ptr):
raise TypeError, "can only cast pointers to other pointers"
+ if CURTYPE == PTRTYPE:
+ return ptr
if CURTYPE.TO._gckind != PTRTYPE.TO._gckind:
raise TypeError("cast_opaque_ptr() cannot change the gc status: "
"%s to %s" % (CURTYPE, PTRTYPE))
@@ -1151,12 +1153,13 @@
if isinstance(self._T, FuncType):
return llmemory.fakeaddress(self)
elif isinstance(self._obj, _subarray):
- # return an address built as an offset in the whole array
- parent, parentindex = parentlink(self._obj)
- T = typeOf(parent)
- addr = llmemory.fakeaddress(normalizeptr(_ptr(Ptr(T), parent)))
- addr += llmemory.itemoffsetof(T, parentindex)
- return addr
+ return llmemory.fakeaddress(self)
+## # return an address built as an offset in the whole array
+## parent, parentindex = parentlink(self._obj)
+## T = typeOf(parent)
+## addr = llmemory.fakeaddress(normalizeptr(_ptr(Ptr(T), parent)))
+## addr += llmemory.itemoffsetof(T, parentindex)
+## return addr
else:
# normal case
return llmemory.fakeaddress(normalizeptr(self))
@@ -1417,7 +1420,16 @@
raise
def setitem(self, index, value):
- self.items[index] = value
+ try:
+ self.items[index] = value
+ except IndexError:
+ if (self._TYPE._hints.get('isrpystring', False) and
+ index == len(self.items)):
+ # special hack for the null terminator: can overwrite it
+ # with another null
+ assert value == '\x00'
+ return
+ raise
assert not '__dict__' in dir(_array)
assert not '__dict__' in dir(_struct)
@@ -1432,6 +1444,11 @@
_parentable.__init__(self, TYPE)
self._setparentstructure(parent, baseoffset_or_fieldname)
+ def __repr__(self):
+
+ return '<_subarray at %r in %r>' % (self._parent_index,
+ self._parentstructure())
+
def getlength(self):
assert isinstance(self._TYPE, FixedSizeArray)
return self._TYPE.length
@@ -1484,6 +1501,46 @@
raise NotImplementedError('_subarray._getid()')
+class _arraylenref(_parentable):
+ """Pseudo-reference to the length field of an array.
+ Only used internally by llmemory to implement ArrayLengthOffset.
+ """
+ _kind = "arraylenptr"
+ _cache = weakref.WeakKeyDictionary() # array -> _arraylenref
+
+ def __init__(self, array):
+ TYPE = FixedSizeArray(Signed, 1)
+ _parentable.__init__(self, TYPE)
+ self.array = array
+
+ def getlength(self):
+ return 1
+
+ def getbounds(self):
+ return 0, 1
+
+ def getitem(self, index, uninitialized_ok=False):
+ assert index == 0
+ return self.array.getlength()
+
+ def setitem(self, index, value):
+ assert index == 0
+ if value != self.array.getlength():
+ raise Exception("can't change the length of an array")
+
+ def _makeptr(array, solid=False):
+ try:
+ lenref = _arraylenref._cache[array]
+ except KeyError:
+ lenref = _arraylenref(array)
+ _arraylenref._cache[array] = lenref
+ return _ptr(Ptr(lenref._TYPE), lenref, solid)
+ _makeptr = staticmethod(_makeptr)
+
+ def _getid(self):
+ raise NotImplementedError('_arraylenref._getid()')
+
+
class _func(_container):
def __init__(self, TYPE, **attrs):
self._TYPE = TYPE
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py Wed Jan 3 16:26:37 2007
@@ -9,10 +9,10 @@
s.x = 123
s.y = 456
a = fakeaddress(s)
- assert a.get() == s
+ assert a.ref() == s
b = a + FieldOffset(S, 'x')
- assert b.get() == 123
- b.set(234)
+ assert b.signed[0] == 123
+ b.signed[0] = 234
assert s.x == 234
def test_composite():
@@ -22,10 +22,10 @@
s2.s.x = 123
s2.s.y = 456
a = fakeaddress(s2)
- assert a.get() == s2
+ assert a.ref() == s2
b = a + FieldOffset(S2, 's') + FieldOffset(S1, 'x')
- assert b.get() == 123
- b.set(234)
+ assert b.signed[0] == 123
+ b.signed[0] = 234
assert s2.s.x == 234
def test_array():
@@ -36,8 +36,8 @@
b = a + ArrayItemsOffset(A)
b += ItemOffset(lltype.Signed)*2
b += ItemOffset(lltype.Signed)
- assert b.get() == 123
- b.set(14)
+ assert b.signed[0] == 123
+ b.signed[0] = 14
assert x[3] == 14
def test_dont_mix_offsets_and_ints():
Modified: pypy/dist/pypy/rpython/memory/gcheader.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gcheader.py (original)
+++ pypy/dist/pypy/rpython/memory/gcheader.py Wed Jan 3 16:26:37 2007
@@ -17,8 +17,9 @@
def header_of_object(self, gcptr):
return self.obj2header[gcptr._as_obj()]
- def object_from_header(self, headerptr):
+ def object_from_header(headerptr):
return header2obj[headerptr._as_obj()]
+ object_from_header = staticmethod(object_from_header)
def get_header(self, gcptr):
return self.obj2header.get(gcptr._as_obj(), None)
Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/framework.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform/framework.py Wed Jan 3 16:26:37 2007
@@ -24,10 +24,10 @@
use_stackless = False
extra_static_slots = 0
finished_tables = False
+ root_stack_depth = 163840
from pypy.rpython.memory.gc import MarkSweepGC as GCClass
- GC_PARAMS = {'start_heap_size': 8*1024*1024 # XXX adjust
- }
+ GC_PARAMS = {'start_heap_size': 8*1024*1024} # XXX adjust
def __init__(self, translator):
from pypy.rpython.memory.support import get_address_linked_list
@@ -228,7 +228,7 @@
def build_stack_root_iterator(self):
gcdata = self.gcdata
sizeofaddr = llmemory.sizeof(llmemory.Address)
- rootstacksize = sizeofaddr * 163840 # XXX adjust
+ rootstacksize = sizeofaddr * self.root_stack_depth
class StackRootIterator:
_alloc_flavor_ = 'raw'
Modified: pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform/test/test_framework.py Wed Jan 3 16:26:37 2007
@@ -8,7 +8,8 @@
import py
class FrameworkGcPolicy2(FrameworkGcPolicy):
- transformerclass = FrameworkGCTransformer
+ class transformerclass(FrameworkGCTransformer):
+ root_stack_depth = 100
def test_framework_simple():
def g(x):
Modified: pypy/dist/pypy/translator/c/database.py
==============================================================================
--- pypy/dist/pypy/translator/c/database.py (original)
+++ pypy/dist/pypy/translator/c/database.py Wed Jan 3 16:26:37 2007
@@ -4,7 +4,6 @@
ContainerType, OpaqueType, FixedSizeArray, _uninitialized
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem.llmemory import Address
-from pypy.rpython.memory.lladdress import NULL
from pypy.tool.sourcetools import valid_identifier
from pypy.translator.c.primitive import PrimitiveName, PrimitiveType
from pypy.translator.c.primitive import PrimitiveErrorValue
@@ -139,7 +138,6 @@
try:
node = self.containernodes[container]
except KeyError:
- assert not self.completed
T = typeOf(container)
if isinstance(T, (lltype.Array, lltype.Struct)):
if hasattr(self.gctransformer, 'consider_constant'):
@@ -150,6 +148,10 @@
self.containerlist.append(node)
kind = getattr(node, 'nodekind', '?')
self.containerstats[kind] = self.containerstats.get(kind, 0) + 1
+ if self.completed:
+ assert not node.globalcontainer
+ # non-global containers are found very late, e.g. _subarrays
+ # via addresses introduced by the GC transformer
return node
def get(self, obj):
Modified: pypy/dist/pypy/translator/c/primitive.py
==============================================================================
--- pypy/dist/pypy/translator/c/primitive.py (original)
+++ pypy/dist/pypy/translator/c/primitive.py Wed Jan 3 16:26:37 2007
@@ -2,11 +2,10 @@
from pypy.rlib.objectmodel import Symbolic, ComputedIntSymbolic
from pypy.rlib.objectmodel import CDefinedIntSymbolic
from pypy.rpython.lltypesystem.lltype import *
-from pypy.rpython.lltypesystem.llmemory import Address, fakeaddress, \
+from pypy.rpython.lltypesystem.llmemory import Address, \
AddressOffset, ItemOffset, ArrayItemsOffset, FieldOffset, \
CompositeOffset, ArrayLengthOffset, WeakGcAddress, fakeweakaddress, \
GCHeaderOffset
-from pypy.rpython.memory.lladdress import NULL
from pypy.translator.c.support import cdecl
# ____________________________________________________________
@@ -99,24 +98,10 @@
return '%d' % ord(value)
def name_address(value, db):
- if value is NULL:
- return 'NULL'
- assert isinstance(value, fakeaddress)
- if value.offset is None:
- if value.ob is None:
- return 'NULL'
- else:
- if isinstance(typeOf(value.ob), ContainerType):
- return db.getcontainernode(value.ob).ptrname
- else:
- return db.get(value.ob)
+ if value:
+ return db.get(value.ref())
else:
- if isinstance(typeOf(value.ob), ContainerType):
- base = db.getcontainernode(value.ob).ptrname
- else:
- base = db.get(value.ob)
-
- return '(void*)(((char*)(%s)) + (%s))'%(base, db.get(value.offset))
+ return 'NULL'
def name_weakgcaddress(value, db):
assert isinstance(value, fakeweakaddress)
Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py (original)
+++ pypy/dist/pypy/translator/llvm/database.py Wed Jan 3 16:26:37 2007
@@ -147,8 +147,8 @@
if type_ is llmemory.Address:
# prepare the constant data which this address references
assert isinstance(value, llmemory.fakeaddress)
- if value.ob is not None:
- self.prepare_constant(lltype.typeOf(value.ob), value.ob)
+ if value:
+ self.prepare_constant(lltype.typeOf(value.ptr), value.ptr)
return
if isinstance(type_, lltype.Ptr) and isinstance(value._obj, int):
@@ -181,8 +181,8 @@
# special cases for address
if ct is llmemory.Address:
fakedaddress = const_or_var.value
- if fakedaddress is not None and fakedaddress.ob is not None:
- ptrvalue = fakedaddress.ob
+ if fakedaddress:
+ ptrvalue = fakedaddress.ptr
ct = lltype.typeOf(ptrvalue)
else:
return
@@ -465,41 +465,14 @@
return repr
def repr_address(self, type_, value):
- if value is NULL:
+ if not value:
return 'null'
-
- assert isinstance(value, llmemory.fakeaddress)
-
- if value.offset is None:
- if value.ob is None:
- return 'null'
- else:
- obj = value.ob._obj
- typename = self.database.repr_type(lltype.typeOf(obj))
- ref = self.database.repr_name(obj)
- else:
- from_, indices, to = self.get_offset(value.offset)
- indices_as_str = ", ".join("%s %s" % (w, i) for w, i in indices)
-
- #original_typename = self.database.repr_type(from_)
- #orignal_ref = self.database.repr_name(value.ob._obj)
- #
- #typename = self.database.repr_type(to)
- #ref = "getelementptr(%s* %s, %s)" % (original_typename,
- # orignal_ref,
- # indices_as_str)
-
- ptrtype = self.database.repr_type(lltype.Ptr(from_))
- node = self.database.obj2node[value.ob._obj]
- parentref = node.get_pbcref(ptrtype)
-
- typename = self.database.repr_type(to)
- ref = "getelementptr(%s %s, %s)" % (ptrtype, parentref,
- indices_as_str)
-
+ obj = value.ptr._obj
+ typename = self.database.repr_type(lltype.typeOf(obj))
+ ref = self.database.repr_name(obj)
res = "cast(%s* %s to sbyte*)" % (typename, ref)
- return res
-
+ return res
+
def repr_weakgcaddress(self, type_, value):
assert isinstance(value, llmemory.fakeweakaddress)
log.WARNING("XXX weakgcaddress completely ignored...")
From arigo at codespeak.net Wed Jan 3 16:27:18 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 3 Jan 2007 16:27:18 +0100 (CET)
Subject: [pypy-svn] r36121 - pypy/dist/pypy/rpython/memory/test
Message-ID: <20070103152718.5218B10070@code0.codespeak.net>
Author: arigo
Date: Wed Jan 3 16:27:16 2007
New Revision: 36121
Modified:
pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
Log:
Tweaks to this test file.
Modified: pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py Wed Jan 3 16:27:16 2007
@@ -234,6 +234,7 @@
class gcpolicy(gc.FrameworkGcPolicy):
class transformerclass(framework.FrameworkGCTransformer):
GC_PARAMS = {'start_heap_size': 4096 }
+ root_stack_depth = 200
gcname = "framework"
def heap_usage(self, statistics):
@@ -644,8 +645,10 @@
class gcpolicy(gc.StacklessFrameworkGcPolicy):
class transformerclass(stacklessframework.StacklessFrameworkGCTransformer):
GC_PARAMS = {'start_heap_size': 4096 }
+ root_stack_depth = 200
def test_x_become(self):
+ from pypy.rlib import objectmodel
S = lltype.GcStruct("S", ('x', lltype.Signed))
def f():
x = lltype.malloc(S)
@@ -656,6 +659,9 @@
llop.gc_x_become(lltype.Void,
llmemory.cast_ptr_to_adr(x),
llmemory.cast_ptr_to_adr(y))
+ # keep 'y' alive until the x_become() is finished, because in
+ # theory it could go away as soon as only its address is present
+ objectmodel.keepalive_until_here(y)
return z.x
run = self.runner(f)
res = run([])
@@ -672,3 +678,4 @@
class transformerclass(framework.FrameworkGCTransformer):
from pypy.rpython.memory.gc import SemiSpaceGC as GCClass
GC_PARAMS = {'space_size': 4096 }
+ root_stack_depth = 200
From arigo at codespeak.net Wed Jan 3 16:48:05 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 3 Jan 2007 16:48:05 +0100 (CET)
Subject: [pypy-svn] r36122 - in pypy/dist/pypy/rlib/rctypes: . test
Message-ID: <20070103154805.831E510068@code0.codespeak.net>
Author: arigo
Date: Wed Jan 3 16:48:03 2007
New Revision: 36122
Modified:
pypy/dist/pypy/rlib/rctypes/implementation.py
pypy/dist/pypy/rlib/rctypes/rpointer.py
pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
Log:
Recursive structures seem to work now.
Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py Wed Jan 3 16:48:03 2007
@@ -1,5 +1,6 @@
import py
from pypy.annotation import model as annmodel
+from pypy.tool.tls import tlsobject
from pypy.rlib.rctypes import rctypesobject
from pypy.rpython import extregistry, controllerentry
from pypy.rpython.error import TyperError
@@ -24,6 +25,9 @@
self.ctype = ctype
self.instance_cache = {}
+ def setup(self):
+ pass
+
def register_for_type(cls, ctype):
class Entry(CTypesCallEntry):
_about_ = ctype
@@ -109,12 +113,29 @@
class CTypesCallEntry(ControllerEntry):
def getcontroller(self, *args_s):
ctype = self.instance
- return self._controller_(ctype)
+ return _build_controller(self._controller_, ctype)
class CTypesObjEntry(ControllerEntryForPrebuilt):
def getcontroller(self):
ctype = self.type
- return self._controller_(ctype)
+ return _build_controller(self._controller_, ctype)
+
+TLS = tlsobject()
+def _build_controller(cls, ctype):
+ if hasattr(TLS, 'pending'):
+ # recursive case
+ controller = cls(ctype)
+ TLS.pending.append(controller)
+ else:
+ # non-recursive case
+ TLS.pending = []
+ controller = cls(ctype)
+ pending = TLS.pending
+ del TLS.pending
+ pending.append(controller)
+ for c1 in pending:
+ c1.setup()
+ return controller
def getcontroller(ctype):
"""Return the CTypeController instance corresponding to the given ctype."""
Modified: pypy/dist/pypy/rlib/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rpointer.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rpointer.py Wed Jan 3 16:48:03 2007
@@ -13,9 +13,12 @@
def __init__(self, ctype):
CTypeController.__init__(self, ctype)
- self.contentscontroller = getcontroller(ctype._type_)
- self.knowntype = rctypesobject.RPointer(
- self.contentscontroller.knowntype)
+ self.knowntype = rctypesobject.RPointer(None)
+
+ def setup(self):
+ if not hasattr(self, 'contentscontroller'):
+ self.contentscontroller = getcontroller(self.ctype._type_)
+ self.knowntype.setpointertype(self.contentscontroller.knowntype)
def new(self, ptrto=None):
obj = self.knowntype.allocate()
Modified: pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py Wed Jan 3 16:48:03 2007
@@ -144,7 +144,6 @@
assert res == 121
def test_struct_with_pointer_to_self(self):
- py.test.skip("in-progress")
PS = POINTER('S')
class S(Structure):
_fields_ = [('l', PS), ('r', PS)]
From arigo at codespeak.net Wed Jan 3 17:30:24 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 3 Jan 2007 17:30:24 +0100 (CET)
Subject: [pypy-svn] r36124 - in pypy/dist/pypy: rlib/rctypes
rlib/rctypes/test rpython
Message-ID: <20070103163024.C844D10068@code0.codespeak.net>
Author: arigo
Date: Wed Jan 3 17:30:22 2007
New Revision: 36124
Modified:
pypy/dist/pypy/rlib/rctypes/implementation.py
pypy/dist/pypy/rlib/rctypes/rchar_p.py
pypy/dist/pypy/rlib/rctypes/rprimitive.py
pypy/dist/pypy/rlib/rctypes/rstruct.py
pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
pypy/dist/pypy/rpython/controllerentry.py
Log:
Minimally-tested support for keyword arguments in contructors,
used for the constructor of ctypes Structures.
Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py Wed Jan 3 17:30:22 2007
@@ -69,6 +69,9 @@
raise TypeError("cannot store a value into a non-primitive ctype")
store_value._annspecialcase_ = 'specialize:arg(0)'
+ def default_ctype_value(self):
+ return self.ctype()
+
# extension to the setattr/setitem support: if the new value is actually
# a CTypeControlled instance as well, reveal it automatically (i.e. turn
# it into an rctypesobject) and call a method with a different name.
@@ -111,7 +114,7 @@
class CTypesCallEntry(ControllerEntry):
- def getcontroller(self, *args_s):
+ def getcontroller(self, *args_s, **kwds_s):
ctype = self.instance
return _build_controller(self._controller_, ctype)
Modified: pypy/dist/pypy/rlib/rctypes/rchar_p.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rchar_p.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rchar_p.py Wed Jan 3 17:30:22 2007
@@ -27,6 +27,9 @@
return_value = get_value
store_value = set_value
+ def default_ctype_value(self):
+ return None
+
def is_true(self, obj):
return obj.get_value() is not None
Modified: pypy/dist/pypy/rlib/rctypes/rprimitive.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rprimitive.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rprimitive.py Wed Jan 3 17:30:22 2007
@@ -80,6 +80,9 @@
return_value = get_value
store_value = set_value
+ def default_ctype_value(self):
+ return self.ctype().value
+
def is_true(self, obj):
llvalue = self.get_value(obj)
if self.is_char_type:
Modified: pypy/dist/pypy/rlib/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rstruct.py Wed Jan 3 17:30:22 2007
@@ -75,6 +75,61 @@
fieldbox = controller.convert(getattr(x, name))
self.setboxattr(obj, name, fieldbox)
+ def insert_constructor_keywords(self, lst, prefix, kwds):
+ lst = list(lst)
+ kwds = kwds.copy()
+ for index, (name, field_ctype) in enumerate(self.ctype._fields_):
+ if prefix+name in kwds:
+ value = kwds.pop(prefix+name)
+ while len(lst) <= index:
+ lst.append(None)
+ if lst[index] is not None:
+ raise TypeError("duplicate value for argument %r" % name)
+ lst[index] = value
+ if kwds:
+ raise TypeError("unknown keyword(s): %r" % (kwds.keys(),))
+ return lst
+
+ def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
+ if kwds_s:
+ args_s = self.insert_constructor_keywords(args_s, 's_', kwds_s)
+ for i in range(len(args_s)):
+ if args_s[i] is None:
+ name, controller = self.fieldcontrollers[i]
+ x = controller.default_ctype_value()
+ args_s[i] = bookkeeper.immutablevalue(x)
+ return CTypeController.ctrl_new(self, *args_s)
+
+ def rtype_new(self, hop, **kwds_i):
+ if kwds_i:
+ lst = range(hop.nb_args)
+ for key, index in kwds_i.items():
+ lst[index] = None
+ lst = self.insert_constructor_keywords(lst, 'i_', kwds_i)
+ hop2 = hop.copy()
+ hop2.nb_args = len(lst)
+ hop2.args_v = []
+ hop2.args_s = []
+ hop2.args_r = []
+ for i, index in enumerate(lst):
+ if index is not None:
+ v = hop.args_v[index]
+ s = hop.args_s[index]
+ r = hop.args_r[index]
+ else:
+ # must insert a default value
+ from pypy.objspace.flow.model import Constant
+ name, controller = self.fieldcontrollers[i]
+ x = controller.default_ctype_value()
+ v = Constant(x)
+ s = hop.rtyper.annotator.bookkeeper.immutablevalue(x)
+ r = hop.rtyper.getrepr(s)
+ hop2.args_v.append(v)
+ hop2.args_s.append(s)
+ hop2.args_r.append(r)
+ hop = hop2
+ return CTypeController.rtype_new(self, hop)
+
StructCTypeController.register_for_metatype(StructType)
Modified: pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py Wed Jan 3 17:30:22 2007
@@ -179,26 +179,26 @@
assert res == 289
def test_specialize_constructor_args(self):
- py.test.skip("in-progress")
+ #py.test.skip("in-progress")
class S(Structure):
_fields_ = [('x', c_int),
('y', c_char)]
- def func(x, y):
+ def func(x, y, n):
s0 = S(x)
s1 = S(x, y)
s2 = S(y=y)
s3 = S(x, y=y)
- return (s0, s1, s2, s3)
+ s = [s0, s1, s2, s3][n]
+ return s.x * 100 + ord(s.y)
- res = interpret(func, [4, '?'])
- assert res.item0.c_data.c_x == 4
- assert res.item0.c_data.c_y == '\x00'
- assert res.item1.c_data.c_x == 4
- assert res.item1.c_data.c_y == '?'
- assert res.item2.c_data.c_x == 0
- assert res.item2.c_data.c_y == '?'
- assert res.item3.c_data.c_x == 4
- assert res.item3.c_data.c_y == '?'
+ res = interpret(func, [4, '?', 0])
+ assert res == 400
+ res = interpret(func, [4, '?', 1])
+ assert res == 463
+ res = interpret(func, [4, '?', 2])
+ assert res == 63
+ res = interpret(func, [4, '?', 3])
+ assert res == 463
def test_specialize_bad_constructor_args(self):
py.test.skip("in-progress")
Modified: pypy/dist/pypy/rpython/controllerentry.py
==============================================================================
--- pypy/dist/pypy/rpython/controllerentry.py (original)
+++ pypy/dist/pypy/rpython/controllerentry.py Wed Jan 3 17:30:22 2007
@@ -8,20 +8,19 @@
class ControllerEntry(ExtRegistryEntry):
- def compute_result_annotation(self, *args_s):
- cls = self.instance
- controller = self.getcontroller(*args_s)
- return controller.ctrl_new(*args_s)
+ def compute_result_annotation(self, *args_s, **kwds_s):
+ controller = self.getcontroller(*args_s, **kwds_s)
+ return controller.ctrl_new_ex(self.bookkeeper, *args_s, **kwds_s)
- def getcontroller(self, *args_s):
+ def getcontroller(self, *args_s, **kwds_s):
return self._controller_()
- def specialize_call(self, hop):
+ def specialize_call(self, hop, **kwds_i):
if hop.s_result == annmodel.s_ImpossibleValue:
raise TyperError("object creation always raises: %s" % (
hop.spaceop,))
controller = hop.s_result.controller
- return controller.rtype_new(hop)
+ return controller.rtype_new(hop, **kwds_i)
@@ -65,13 +64,19 @@
return controlled_instance_is_box(self, obj)
is_box._annspecialcase_ = 'specialize:arg(0)'
- def ctrl_new(self, *args_s):
+ def ctrl_new(self, *args_s, **kwds_s):
+ if kwds_s:
+ raise TypeError("cannot handle keyword arguments in %s" % (
+ self.new,))
s_real_obj = delegate(self.new, *args_s)
if s_real_obj == annmodel.s_ImpossibleValue:
return annmodel.s_ImpossibleValue
else:
return SomeControlledInstance(s_real_obj, controller=self)
+ def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
+ return self.ctrl_new(*args_s, **kwds_s)
+
def rtype_new(self, hop):
from pypy.rpython.rcontrollerentry import rtypedelegate
return rtypedelegate(self.new, hop, revealargs=[], revealresult=True)
From cfbolz at codespeak.net Wed Jan 3 20:16:47 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 3 Jan 2007 20:16:47 +0100 (CET)
Subject: [pypy-svn] r36130 - pypy/dist/pypy/lang/js/test
Message-ID: <20070103191647.483F210072@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 3 20:16:46 2007
New Revision: 36130
Modified:
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
actually _call_ the js_is_on_path helper to skip tests when the js binary (used
for parsing) is not there.
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Wed Jan 3 20:16:46 2007
@@ -17,7 +17,7 @@
except py.error.ENOENT:
py.test.skip("js binary not found")
-
+js_is_on_path()
class TestInterp(object):
def test_simple(self):
From cfbolz at codespeak.net Wed Jan 3 21:15:00 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 3 Jan 2007 21:15:00 +0100 (CET)
Subject: [pypy-svn] r36133 - pypy/dist/pypy/translator/goal
Message-ID: <20070103201500.3DA8E10074@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 3 21:15:00 2007
New Revision: 36133
Modified:
pypy/dist/pypy/translator/goal/targetpypystandalone.py
Log:
I _think_ that this is all what's needed to make the --oldstyle option working
for targetpypystandalone.
Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py
==============================================================================
--- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original)
+++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Wed Jan 3 21:15:00 2007
@@ -146,9 +146,9 @@
def get_entry_point(self, config):
space = make_objspace(config)
- # disable translation of the whole of classobjinterp.py
- StdObjSpace.setup_old_style_classes = lambda self: None
-
+ if not self.config.objspace.std.oldstyle:
+ # disable translation of the whole of classobjinterp.py
+ StdObjSpace.setup_old_style_classes = lambda self: None
# manually imports app_main.py
filename = os.path.join(this_dir, 'app_main.py')
From santagada at codespeak.net Wed Jan 3 21:17:48 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Wed, 3 Jan 2007 21:17:48 +0100 (CET)
Subject: [pypy-svn] r36134 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070103201748.5FF7B10077@code0.codespeak.net>
Author: santagada
Date: Wed Jan 3 21:17:26 2007
New Revision: 36134
Removed:
pypy/dist/pypy/lang/js/astgen.py
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
more tests and some code cleanup
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Wed Jan 3 21:17:26 2007
@@ -1,8 +1,30 @@
-from pypy.lang.js.astgen import *
from pypy.lang.js.jsparser import parse
from pypy.lang.js.jsobj import *
+class Node(object):
+ # TODO Add line info for debug
+# def __init__(self, lineno = 1):
+# self.lineno = lineno
+ pass
+
+class BinaryOp(Node):
+ def __init__(self, left, right):
+ self.left = left
+ self.right = right
+
+class BinaryComparisonOp(BinaryOp):
+ """super class for binary operators"""
+ def call(self, ctx):
+ s2 = self.left.call(ctx).GetValue()
+ s4 = self.right.call(ctx).GetValue()
+ return self.decision(s2, s4)
+
+
+class BinaryLogicOp(BinaryOp):
+ """super class for binary operators"""
+ pass
+
def writer(x):
print x
@@ -27,14 +49,34 @@
"""run the interpreter"""
return self.script.call(self.global_context)
+class PropertyInit(Node):
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+ def __repr__(self):
+ return "<%s : %s>"%(str(self.name), str(self.value))
+
+
+
+class Undefined(Node):
+ def __init__(self):
+ pass
+
+class Array(Node):
+ def __init__(self, items=()):
+ self.items = items
-class __extend__(Array):
def call(self, ctx):
d = dict(enumerate(self.items))
return W_Array(d)
-class __extend__(Assign):
+class Assign(Node):
+ def __init__(self, LHSExp, AssignmentExp):
+ self.LHSExp = LHSExp
+ self.AssignmentExp = AssignmentExp
+
def call(self, ctx):
print "Assign LHS = ", self.LHSExp
v1 = self.LHSExp.call(ctx)
@@ -43,7 +85,10 @@
v1.PutValue(v3, ctx)
return v3
-class __extend__(Block):
+class Block(Node):
+ def __init__(self, nodes):
+ self.nodes = nodes
+
def call(self, ctx):
try:
last = w_Undefined
@@ -53,7 +98,11 @@
except ExecutionReturned, e:
return e.value
-class __extend__(Call):
+class Call(Node):
+ def __init__(self, identifier, arglist):
+ self.identifier = identifier
+ self.arglist = arglist
+
def call(self, ctx):
name = self.identifier.get_literal()
if name == 'print':
@@ -64,23 +113,33 @@
retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.call(ctx)])
return retval
-class __extend__(Comma):
+class Comma(BinaryOp):
def call(self, ctx):
self.left.call(ctx)
return self.right.call(ctx)
-class __extend__(Dot):
+class Dot(BinaryOp):
def call(self, ctx):
w_obj = self.left.call(ctx).GetValue().ToObject()
name = self.right.get_literal()
return Reference(name, w_obj)
-class __extend__(Function):
+class Function(Node):
+ def __init__(self, name, params, body):
+ self.name = name
+ self.params = params
+ self.body = body
+
def call(self, ctx):
w_obj = W_FunctionObject(self, ctx)
return w_obj
-class __extend__(Identifier):
+class Identifier(Node):
+ def __init__(self, name, initialiser=None):
+ self.name = name
+ self.initialiser = initialiser
+ def __str__(self):
+ return ""%(str(self.name), str(self.initialiser))
def call(self, ctx):
if self.initialiser is not None:
ref = ctx.resolve_identifier(self.name)
@@ -90,7 +149,12 @@
def get_literal(self):
return self.name
-class __extend__(If):
+class If(Node):
+ def __init__(self, condition, thenPart=None, elsePart=None):
+ self.condition = condition
+ self.thenPart = thenPart
+ self.elsePart = elsePart
+
def call(self, ctx=None):
temp = self.condition.call(ctx)
print "if condition = ", temp
@@ -99,8 +163,11 @@
else:
return self.elsePart.call(ctx)
-class __extend__(Group):
- def call(self, ctx = None):
+class Group(Node):
+ def __init__(self, expr):
+ self.expr = expr
+
+ def call(self, ctx):
return self.expr.call(ctx)
def ARC(x, y):
@@ -124,7 +191,7 @@
else:
pass
-class __extend__(Or):
+class Or(BinaryLogicOp):
def call(self, ctx):
s2 = self.left.call(ctx).GetValue()
if s2.ToBoolean():
@@ -132,7 +199,7 @@
s4 = self.right.call(ctx).GetValue()
return s4
-class __extend__(And):
+class And(BinaryLogicOp):
def call(self, ctx):
s2 = self.left.call(ctx).GetValue()
if not s2.ToBoolean():
@@ -140,14 +207,7 @@
s4 = self.right.call(ctx).GetValue()
return s4
-
-class __extend__(BinaryOperator):
- def call(self, ctx):
- s2 = self.left.call(ctx).GetValue()
- s4 = self.right.call(ctx).GetValue()
- return self.decision(s2, s4)
-
-class __extend__(Ge):
+class Ge(BinaryComparisonOp):
def decision(self, op1, op2):
s5 = ARC(op1, op2)
if s5 is None or s5:
@@ -155,7 +215,7 @@
else:
return W_Boolean(True)
-class __extend__(Gt):
+class Gt(BinaryComparisonOp):
def decision(self, op1, op2):
s5 = ARC(op2, op1)
if s5 is None:
@@ -163,7 +223,7 @@
else:
return W_Boolean(s5)
-class __extend__(Le):
+class Le(BinaryComparisonOp):
def decision(self, op1, op2):
s5 = ARC(op2, op1)
if s5 is None or s5:
@@ -171,7 +231,7 @@
else:
return W_Boolean(True)
-class __extend__(Lt):
+class Lt(BinaryComparisonOp):
def decision(self, op1, op2):
s5 = ARC(op1, op2)
if s5 is None:
@@ -187,16 +247,16 @@
r = x.ToNumber() == y.ToNumber()
return r
-class __extend__(Eq):
+class Eq(BinaryComparisonOp):
def decision(self, op1, op2):
return W_Boolean(AEC(op1, op2))
-class __extend__(Ne):
+class Ne(BinaryComparisonOp):
def decision(self, op1, op2):
return W_Boolean(not AEC(op1, op2))
-class __extend__(In):
+class In(BinaryComparisonOp):
def decision(self, op1, op2):
if not isinstance(op2, W_Object):
raise ThrowException("TypeError")
@@ -204,7 +264,11 @@
return W_Boolean(op2.HasProperty(name))
-class __extend__(Index):
+class Index(Node):
+ def __init__(self, left, expr):
+ self.left = left
+ self.expr = expr
+
def call(self, ctx):
w_obj = self.left.call(ctx).GetValue()
w_member = self.expr.call(ctx).GetValue()
@@ -212,19 +276,24 @@
name = w_member.ToString()
return w_obj.Get(name)
-class __extend__(List):
+class List(Node):
+ def __init__(self, nodes):
+ self.nodes = nodes
def call(self, ctx):
print "nodes = ", self.nodes
return [node.call(ctx) for node in self.nodes]
-class __extend__(Minus):
+class Minus(BinaryComparisonOp):
def decision(self, op1, op2):
x = op1.ToNumber()
y = op2.ToNumber()
return W_Number(x - y)
-class __extend__(New):
- def call(self, ctx=None):
+class New(Node):
+ def __init__(self, identifier):
+ self.identifier = identifier
+
+ def call(self, ctx):
obj = W_Object()
#it should be undefined... to be completed
constructor = ctx.resolve_identifier(self.identifier).GetValue()
@@ -232,14 +301,20 @@
constructor.Call(ctx, this = obj)
return obj
-class __extend__(Number):
+class Number(Node):
+ def __init__(self, num):
+ self.num = num
+
def call(self, ctx):
return W_Number(self.num)
def get_literal(self):
return W_Number(self.num).ToString()
-class __extend__(ObjectInit):
+class ObjectInit(Node):
+ def __init__(self, properties):
+ self.properties = properties
+
def call(self, ctx):
w_obj = W_Object()
print "properties = ", self.properties
@@ -250,7 +325,7 @@
w_obj.Put(name, w_expr)
return w_obj
-class __extend__(Plus):
+class Plus(BinaryComparisonOp):
def decision(self, op1, op2):
prim_left = op1.ToPrimitive('Number')
prim_right = op2.ToPrimitive('Number')
@@ -263,7 +338,12 @@
num_right = prim_right.ToNumber()
return W_Number(num_left + num_right)
-class __extend__(Script):
+class Script(Node):
+ def __init__(self, nodes, var_decl, func_decl):
+ self.nodes = nodes
+ self.var_decl = var_decl
+ self.func_decl = func_decl
+
def call(self, ctx):
for var in self.var_decl:
ctx.variable.Put(var.name, w_Undefined)
@@ -279,26 +359,45 @@
except ExecutionReturned, e:
return e.value
-class __extend__(Semicolon):
+class Semicolon(Node):
+ def __init__(self, expr):
+ self.expr = expr
+
def call(self, ctx=None):
return self.expr.call(ctx)
-class __extend__(String):
+class String(Node):
+ def __init__(self, strval):
+ self.strval = strval
+
def call(self, ctx=None):
return W_String(self.strval)
def get_literal(self):
return W_String(self.strval).ToString()
-class __extend__(Return):
+class Return(Node):
+ def __init__(self, expr):
+ self.expr = expr
+
def call(self, ctx):
raise ExecutionReturned(self.expr.call(ctx))
-class __extend__(Throw):
+class Throw(Node):
+ def __init__(self, exception):
+ self.exception = exception
+
def call(self, ctx):
raise ThrowException(self.exception.call(ctx))
-class __extend__(Try):
+class Try(Node):
+ # TODO: rewrite to use 'Undefined'
+ def __init__(self, tryblock, catchblock, finallyblock, catchparam):
+ self.tryblock = tryblock
+ self.catchblock = catchblock
+ self.finallyblock = finallyblock
+ self.catchparam = catchparam
+
def call(self, ctx):
e = None
try:
@@ -321,19 +420,165 @@
return tryresult
-class __extend__(Undefined):
+class Undefined(Node):
def call(self, ctx):
return None
-class __extend__(Vars):
+class Vars(Node):
+ def __init__(self, nodes):
+ self.nodes = nodes
+
def call(self, ctx):
print self.nodes
for var in self.nodes:
print var.name
var.call(ctx)
-class __extend__(While):
+class While(Node):
+ def __init__(self, condition, body):
+ self.condition = condition
+ self.body = body
+
def call(self, ctx):
while self.condition.call(ctx).ToBoolean():
self.body.call(ctx)
+def getlist(d):
+ if 'length' not in d:
+ return []
+ lgt = int(d['length'])
+ output = [from_dict(d[str(i)]) for i in range(lgt)]
+ return output
+
+def build_interpreter(d):
+ return from_dict(d)
+
+# FIXME: Continue the translation from if/elif to this dict map
+build_map = {'ARRAY_INIT':Array,
+ 'ASSIGN': Assign,
+ 'BLOCK': Block}
+
+def from_dict_map(d):
+ if d is None:
+ return d
+ try:
+ build_map[d['type']](d)
+ except KeyError,e:
+ raise NotImplementedError("Don't know how to handle %s" %(d['type'],))
+
+
+
+def from_dict(d):
+ if d is None:
+ return d
+ tp = d['type']
+ if tp == 'ARRAY_INIT':
+ return Array(getlist(d))
+ elif tp == 'ASSIGN':
+ return Assign(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'BLOCK':
+ return Block(getlist(d))
+ elif tp == 'CALL':
+ return Call(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'COMMA':
+ return Comma(from_dict(d['0']),from_dict(d['1']))
+ elif tp == 'DOT':
+ return Dot(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'EQ':
+ return Eq(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'OR':
+ return Or(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'AND':
+ return And(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'FUNCTION':
+ name = d.get('name', '')
+ body = from_dict(d['body'])
+ if d['params'] == '':
+ params = []
+ else:
+ params = d['params'].split(',')
+ f = Function(name, params, body)
+ return f
+ elif tp == 'GROUP':
+ return Group(from_dict(d['0']))
+ elif tp == 'GE':
+ return Ge(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'GT':
+ return Gt(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'IDENTIFIER':
+ return Identifier(d['value'], from_dict(d.get('initializer', None)))
+ elif tp == 'IF':
+ condition = from_dict(d['condition'])
+ if d['thenPart'] == 'null':
+ thenPart = Undefined()
+ else:
+ thenPart = from_dict(d['thenPart'])
+ if d['elsePart'] == 'null':
+ elsePart = Undefined()
+ else:
+ elsePart = from_dict(d['elsePart'])
+ return If(condition,thenPart,elsePart)
+ elif tp == 'IN':
+ return In(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'INDEX':
+ return Index(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'LIST':
+ return List(getlist(d))
+ elif tp == 'LE':
+ return Le(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'LT':
+ return Lt(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'MINUS':
+ return Minus(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'NE':
+ return Ne(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'NEW':
+ return New(d['0']['value'])
+ elif tp == 'NUMBER':
+ return Number(float(d['value']))
+ elif tp == 'OBJECT_INIT':
+ return ObjectInit(getlist(d))
+ elif tp == 'PLUS':
+ return Plus(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'PROPERTY_INIT':
+ return PropertyInit(from_dict(d['0']), from_dict(d['1']))
+ elif tp == 'RETURN':
+ return Return(from_dict(d['value']))
+ elif tp == 'SCRIPT':
+ if isinstance(d['funDecls'], dict):
+ func_decl = [from_dict(d['funDecls']),]
+ else:
+ func_decl = [from_dict(x) for x in d['funDecls']]
+
+ if isinstance(d['varDecls'], dict):
+ var_decl = [from_dict(d['varDecls']),]
+ else:
+ var_decl = [from_dict(x) for x in d['varDecls']]
+ return Script(getlist(d), var_decl, func_decl)
+ elif tp == 'SEMICOLON':
+ return Semicolon(from_dict(d['expression']))
+ elif tp == 'STRING':
+ return String(d['value'])
+ elif tp == 'THIS':
+ return Identifier(d['value'])
+ elif tp == 'THROW':
+ return Throw(from_dict(d['exception']))
+ elif tp == 'TRY':
+ finallyblock = None
+ catchblock = None
+ catchparam = ''
+ if 'finallyBlock' in d:
+ finallyblock = from_dict(d['finallyBlock'])
+ if 'catchClauses' in d:
+ #multiple catch clauses is a spidermonkey extension
+ catchblock = from_dict(d['catchClauses']['block'])
+ catchparam = d['catchClauses']['varName']
+ return Try(from_dict(d['tryBlock']), catchblock, finallyblock, catchparam)
+ elif tp == 'VAR':
+ return Vars(getlist(d))
+ elif tp == 'WHILE':
+ body = from_dict(d['body'])
+ condition = from_dict(d['condition'])
+ return While(condition, body)
+ else:
+ raise NotImplementedError("Dont know how to handler %s" % tp)
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Wed Jan 3 21:17:26 2007
@@ -190,12 +190,30 @@
print "* end of function call return = ", val
return val
+class W_Array(W_Object):
+ def __init__(self, items):
+ W_Object.__init__(self)
+ self.Put('length', W_Number(0))
+
+ def Put(self, P, V):
+ if not isinstance(P, str):
+ P = P.ToString()
+ if not self.CanPut(P): return
+ if P in self.propdict:
+ self.propdict[P].value = V
+ else:
+ try:
+ x = int(P)
+ except: # FIXME: forgot the name of the exception
+ x = -1
+ if self.Get('length') < 0: pass
+ self.propdict[P] = Property(P, V)
+
class W_Undefined(W_Root):
def __str__(self):
return "w_undefined"
def ToNumber(self):
- # XXX make NaN
return NaN
def ToBoolean(self):
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Wed Jan 3 21:17:26 2007
@@ -4,10 +4,9 @@
import py.test
-from pypy.lang.js.astgen import *
from pypy.lang.js import interpreter
from pypy.lang.js.jsparser import parse
-from pypy.lang.js.interpreter import ThrowException
+from pypy.lang.js.interpreter import *
from pypy.lang.js.jsobj import W_Number, W_Object, ExecutionContext
@@ -150,7 +149,7 @@
""", ["test"])
def test_array_initializer(self):
- py.test.skip('not ready yet')
+ py.test.skip("not ready yet")
self.assert_prints("""
x = [];
print(x);
From cfbolz at codespeak.net Wed Jan 3 21:22:27 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 3 Jan 2007 21:22:27 +0100 (CET)
Subject: [pypy-svn] r36135 - pypy/dist/pypy/translator/goal
Message-ID: <20070103202227.E69E210077@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 3 21:22:25 2007
New Revision: 36135
Modified:
pypy/dist/pypy/translator/goal/targetpypystandalone.py
Log:
bad cf, no cookie: cut-n-paste error
Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py
==============================================================================
--- pypy/dist/pypy/translator/goal/targetpypystandalone.py (original)
+++ pypy/dist/pypy/translator/goal/targetpypystandalone.py Wed Jan 3 21:22:25 2007
@@ -146,7 +146,7 @@
def get_entry_point(self, config):
space = make_objspace(config)
- if not self.config.objspace.std.oldstyle:
+ if not config.objspace.std.oldstyle:
# disable translation of the whole of classobjinterp.py
StdObjSpace.setup_old_style_classes = lambda self: None
From cfbolz at codespeak.net Thu Jan 4 00:47:54 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu, 4 Jan 2007 00:47:54 +0100 (CET)
Subject: [pypy-svn] r36136 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20070103234754.F109C10071@code0.codespeak.net>
Author: cfbolz
Date: Thu Jan 4 00:47:53 2007
New Revision: 36136
Modified:
pypy/dist/pypy/objspace/std/dictmultiobject.py
pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py
Log:
implement the iter* methods off most multidict implementations in a more
sensible way: before, most dict implementations first converted themselves to
an rdict, then created the iterator just to throw the converted implementation
away (which makes the iter* methods O(n) instead of O(1)). Now there is a way
better interface that for iteration and most of the dict implementations do
something sensible for iteration.
All tests pass and pypy-withmultidict-c seems to translate on my machine (no, I
am not making the mistake of checkin in untested code again on the same day :-)
).
Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/dist/pypy/objspace/std/dictmultiobject.py Thu Jan 4 00:47:53 2007
@@ -16,7 +16,10 @@
# XXX there are much more types
return (space.is_w(w_lookup_type, space.w_NoneType) or
- space.is_w(w_lookup_type, space.w_int))
+ space.is_w(w_lookup_type, space.w_int) or
+ space.is_w(w_lookup_type, space.w_bool) or
+ space.is_w(w_lookup_type, space.w_float)
+ )
# DictImplementation lattice
@@ -57,11 +60,32 @@
def keys(self):
- return [w_k for w_k in self.iterkeys()]
+ iterator = self.iterkeys()
+ result = []
+ while 1:
+ w_key = iterator.next()
+ if w_key is not None:
+ result.append(w_key)
+ else:
+ return result
def values(self):
- return [w_v for w_v in self.itervalues()]
+ iterator = self.itervalues()
+ result = []
+ while 1:
+ w_value = iterator.next()
+ if w_value is not None:
+ result.append(w_value)
+ else:
+ return result
def items(self):
- return [(w_key, w_value) or w_key, w_value in self.iteritems()]
+ iterator = self.iteritems()
+ result = []
+ while 1:
+ w_item = iterator.next()
+ if w_item is not None:
+ result.append(w_item)
+ else:
+ return result
# the following method only makes sense when the option to use the
# CALL_LIKELY_BUILTIN opcode is set. Otherwise it won't even be seen
@@ -71,6 +95,40 @@
return self.get(w_key)
+# Iterator Implementation base classes
+
+class IteratorImplementation(object):
+ def __init__(self, space, implementation):
+ self.space = space
+ self.dictimplementation = implementation
+ self.len = implementation.length()
+ self.pos = 0
+
+ def next(self):
+ if self.dictimplementation is None:
+ return None
+ if self.len != self.dictimplementation.length():
+ self.len = -1 # Make this error state sticky
+ raise OperationError(self.space.w_RuntimeError,
+ self.space.wrap("dictionary changed size during iteration"))
+ # look for the next entry
+ w_result = self.next_entry()
+ if w_result is not None:
+ self.pos += 1
+ return w_result
+ # no more entries
+ self.dictimplementation = None
+ return None
+
+ def length(self):
+ if self.dictimplementation is not None:
+ return self.len - self.pos
+ return 0
+
+
+
+# concrete subclasses of the above
+
class EmptyDictImplementation(DictImplementation):
def __init__(self, space):
self.space = space
@@ -94,11 +152,11 @@
return 0
def iteritems(self):
- return RDictImplementation(self.space).iteritems()
+ return EmptyIteratorImplementation(self.space, self)
def iterkeys(self):
- return RDictImplementation(self.space).iterkeys()
+ return EmptyIteratorImplementation(self.space, self)
def itervalues(self):
- return RDictImplementation(self.space).itervalues()
+ return EmptyIteratorImplementation(self.space, self)
def keys(self):
return []
@@ -107,6 +165,11 @@
def items(self):
return []
+
+class EmptyIteratorImplementation(IteratorImplementation):
+ def next_entry(self):
+ return None
+
class Entry(object):
def __init__(self):
self.hash = 0
@@ -191,7 +254,9 @@
def values(self):
return [self.entries[i].w_value for i in range(self.valid)]
def items(self):
- return [(e.w_key, e.w_value) for e in [self.entries[i] for i in range(self.valid)]]
+ return [self.space.newtuple([e.w_key, e.w_value])
+ for e in [self.entries[i] for i in range(self.valid)]]
+
class StrEntry(object):
def __init__(self):
@@ -311,8 +376,9 @@
def values(self):
return [self.entries[i].w_value for i in range(self.valid)]
def items(self):
- return [(self.space.wrap(e.key), e.w_value)
- for e in [self.entries[i] for i in range(self.valid)]]
+ return [self.space.newtuple([self.space.wrap(e.key), e.w_value])
+ for e in [self.entries[i] for i in range(self.valid)]]
+
class StrDictImplementation(DictImplementation):
def __init__(self, space):
@@ -358,13 +424,13 @@
return self._as_rdict().get(w_lookup)
def iteritems(self):
- return self._as_rdict().iteritems()
+ return StrItemIteratorImplementation(self.space, self)
def iterkeys(self):
- return self._as_rdict().iterkeys()
+ return StrKeyIteratorImplementation(self.space, self)
def itervalues(self):
- return self._as_rdict().itervalues()
+ return StrValueIteratorImplementation(self.space, self)
def keys(self):
space = self.space
@@ -375,7 +441,8 @@
def items(self):
space = self.space
- return [(space.wrap(key), w_value) for (key, w_value) in self.content.iteritems()]
+ return [space.newtuple([space.wrap(key), w_value])
+ for (key, w_value) in self.content.iteritems()]
def _as_rdict(self):
@@ -384,6 +451,46 @@
newimpl.setitem(self.space.wrap(k), w_v)
return newimpl
+
+# the following are very close copies of the base classes above
+
+class StrKeyIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iterkeys()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key in self.iterator:
+ return self.space.wrap(key)
+ else:
+ return None
+
+class StrValueIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.itervalues()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_value in self.iterator:
+ return w_value
+ else:
+ return None
+
+class StrItemIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for key, w_value in self.iterator:
+ return self.space.newtuple([self.space.wrap(key), w_value])
+ else:
+ return None
+
+
class WaryDictImplementation(StrDictImplementation):
def __init__(self, space):
StrDictImplementation.__init__(self, space)
@@ -440,18 +547,57 @@
return self.content.get(w_lookup, None)
def iteritems(self):
- return self.content.iteritems()
+ return RDictItemIteratorImplementation(self.space, self)
def iterkeys(self):
- return self.content.iterkeys()
+ return RDictKeyIteratorImplementation(self.space, self)
def itervalues(self):
- return self.content.itervalues()
+ return RDictValueIteratorImplementation(self.space, self)
def keys(self):
return self.content.keys()
def values(self):
return self.content.values()
def items(self):
- return self.content.items()
+ return [self.space.newtuple([w_key, w_val])
+ for w_key, w_val in self.content.iteritems()]
+
+
+class RDictKeyIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iterkeys()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_key in self.iterator:
+ return w_key
+ else:
+ return None
+
+class RDictValueIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.itervalues()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_value in self.iterator:
+ return w_value
+ else:
+ return None
+
+class RDictItemIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.content.iteritems()
+
+ def next_entry(self):
+ # note that this 'for' loop only runs once, at most
+ for w_key, w_value in self.iterator:
+ return self.space.newtuple([w_key, w_value])
+ else:
+ return None
+
class SharedStructure(object):
def __init__(self, keys=None, length=0,
@@ -559,13 +705,13 @@
return self.structure.length
def iteritems(self):
- return self._as_rdict().iteritems()
+ return SharedItemIteratorImplementation(self.space, self)
def iterkeys(self):
- return self._as_rdict().iterkeys()
+ return SharedKeyIteratorImplementation(self.space, self)
def itervalues(self):
- return self._as_rdict().itervalues()
+ return SharedValueIteratorImplementation(self.space, self)
def keys(self):
space = self.space
@@ -593,6 +739,49 @@
return newimpl
+class SharedValueIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.values = dictimplementation.entries
+
+ def next(self):
+ if self.pos < self.len:
+ return self.values[self.pos]
+ else:
+ self.values = None
+ return None
+
+class SharedItemIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.structure.keys.iteritems()
+
+ def next_entry(self):
+ implementation = self.dictimplementation
+ assert isinstance(implementation, SharedDictImplementation)
+ for key, index in self.iterator:
+ if index >= 0:
+ w_value = implementation.entries[index]
+ return self.space.newtuple([self.space.wrap(key), w_value])
+ else:
+ return None
+
+class SharedKeyIteratorImplementation(IteratorImplementation):
+ def __init__(self, space, dictimplementation):
+ IteratorImplementation.__init__(self, space, dictimplementation)
+ self.iterator = dictimplementation.structure.keys.iteritems()
+
+ def next_entry(self):
+ implementation = self.dictimplementation
+ assert isinstance(implementation, SharedDictImplementation)
+ for key, index in self.iterator:
+ if index >= 0:
+ w_value = implementation.entries[index]
+ return self.space.wrap(key)
+ else:
+ return None
+
+
import time, py
class DictInfo(object):
@@ -710,15 +899,15 @@
def iteritems(self):
self.info.iteritems += 1
self.info.iterations += 1
- return self.content.iteritems()
+ return RDictItemIteratorImplementation(self.space, self)
def iterkeys(self):
self.info.iterkeys += 1
self.info.iterations += 1
- return self.content.iterkeys()
+ return RDictKeyIteratorImplementation(self.space, self)
def itervalues(self):
self.info.itervalues += 1
self.info.iterations += 1
- return self.content.itervalues()
+ return RDictValueIteratorImplementation(self.space, self)
def keys(self):
self.info.keys += 1
@@ -731,7 +920,9 @@
def items(self):
self.info.items += 1
self.info.listings += 1
- return self.content.items()
+ return [self.space.newtuple([w_key, w_val])
+ for w_key, w_val in self.content.iteritems()]
+
_example = DictInfo()
del DictInfo._dict_infos[-1]
@@ -783,9 +974,10 @@
def unwrap(w_dict, space):
result = {}
- for w_key, w_value in w_dict.implementation.iteritems():
- # generic mixed types unwrap
- result[space.unwrap(w_key)] = space.unwrap(w_value)
+ items = w_dict.implementation.items()
+ for w_pair in items:
+ key, val = space.unwrap(w_pair)
+ result[key] = val
return result
def len(w_self):
@@ -853,7 +1045,7 @@
dict_has_key__DictMulti_ANY = contains__DictMulti_ANY
def iter__DictMulti(space, w_dict):
- return W_DictMultiIter_Keys(space, w_dict.implementation)
+ return W_DictMultiIterObject(space, w_dict.implementation.iterkeys())
def eq__DictMulti_DictMulti(space, w_left, w_right):
if space.is_w(w_left, w_right):
@@ -861,7 +1053,13 @@
if w_left.implementation.length() != w_right.implementation.length():
return space.w_False
- for w_key, w_val in w_left.implementation.iteritems():
+ iteratorimplementation = w_left.implementation.iteritems()
+ while 1:
+ w_item = iteratorimplementation.next()
+ if w_item is None:
+ break
+ w_key = space.getitem(w_item, space.wrap(0))
+ w_val = space.getitem(w_item, space.wrap(1))
w_rightval = w_right.implementation.get(w_key)
if w_rightval is None:
return space.w_False
@@ -874,7 +1072,13 @@
returns the smallest key in acontent for which b's value is different or absent and this value """
w_smallest_diff_a_key = None
w_its_value = None
- for w_key, w_val in aimpl.iteritems():
+ iteratorimplementation = aimpl.iteritems()
+ while 1:
+ w_item = iteratorimplementation.next()
+ if w_item is None:
+ break
+ w_key = space.getitem(w_item, space.wrap(0))
+ w_val = space.getitem(w_item, space.wrap(1))
if w_smallest_diff_a_key is None or space.is_true(space.lt(w_key, w_smallest_diff_a_key)):
w_bvalue = bimpl.get(w_key)
if w_bvalue is None:
@@ -917,7 +1121,7 @@
return w_new
def dict_items__DictMulti(space, w_self):
- return space.newlist([space.newtuple([w_k, w_v]) for w_k, w_v in w_self.implementation.iteritems()])
+ return space.newlist(w_self.implementation.items())
def dict_keys__DictMulti(space, w_self):
return space.newlist(w_self.implementation.keys())
@@ -926,13 +1130,13 @@
return space.newlist(w_self.implementation.values())
def dict_iteritems__DictMulti(space, w_self):
- return W_DictMultiIter_Items(space, w_self.implementation)
+ return W_DictMultiIterObject(space, w_self.implementation.iteritems())
def dict_iterkeys__DictMulti(space, w_self):
- return W_DictMultiIter_Keys(space, w_self.implementation)
+ return W_DictMultiIterObject(space, w_self.implementation.iterkeys())
def dict_itervalues__DictMulti(space, w_self):
- return W_DictMultiIter_Values(space, w_self.implementation)
+ return W_DictMultiIterObject(space, w_self.implementation.itervalues())
def dict_clear__DictMulti(space, w_self):
w_self.implementation = space.emptydictimpl
@@ -977,74 +1181,29 @@
# ____________________________________________________________
# Iteration
+
class W_DictMultiIterObject(W_Object):
from pypy.objspace.std.dicttype import dictiter_typedef as typedef
- def __init__(w_self, space, implementation):
+ def __init__(w_self, space, iteratorimplementation):
w_self.space = space
- w_self.implementation = implementation
- w_self.len = implementation.length()
- w_self.pos = 0
- w_self.setup_iterator()
-
+ w_self.iteratorimplementation = iteratorimplementation
registerimplementation(W_DictMultiIterObject)
-class W_DictMultiIter_Keys(W_DictMultiIterObject):
- def setup_iterator(w_self):
- w_self.iterator = w_self.implementation.iterkeys()
- def next_entry(w_self):
- # note that this 'for' loop only runs once, at most
- for w_key in w_self.iterator:
- return w_key
- else:
- return None
-
-class W_DictMultiIter_Values(W_DictMultiIterObject):
- def setup_iterator(w_self):
- w_self.iterator = w_self.implementation.itervalues()
- def next_entry(w_self):
- # note that this 'for' loop only runs once, at most
- for w_value in w_self.iterator:
- return w_value
- else:
- return None
-
-class W_DictMultiIter_Items(W_DictMultiIterObject):
- def setup_iterator(w_self):
- w_self.iterator = w_self.implementation.iteritems()
- def next_entry(w_self):
- # note that this 'for' loop only runs once, at most
- for w_key, w_value in w_self.iterator:
- return w_self.space.newtuple([w_key, w_value])
- else:
- return None
-
-
def iter__DictMultiIterObject(space, w_dictiter):
return w_dictiter
def next__DictMultiIterObject(space, w_dictiter):
- implementation = w_dictiter.implementation
- if implementation is not None:
- if w_dictiter.len != implementation.length():
- w_dictiter.len = -1 # Make this error state sticky
- raise OperationError(space.w_RuntimeError,
- space.wrap("dictionary changed size during iteration"))
- # look for the next entry
- w_result = w_dictiter.next_entry()
- if w_result is not None:
- w_dictiter.pos += 1
- return w_result
- # no more entries
- w_dictiter.implementation = None
+ iteratorimplementation = w_dictiter.iteratorimplementation
+ w_result = iteratorimplementation.next()
+ if w_result is not None:
+ return w_result
raise OperationError(space.w_StopIteration, space.w_None)
def len__DictMultiIterObject(space, w_dictiter):
- implementation = w_dictiter.implementation
- if implementation is None or w_dictiter.len == -1:
- return space.wrap(0)
- return space.wrap(w_dictiter.len - w_dictiter.pos)
+ iteratorimplementation = w_dictiter.iteratorimplementation
+ return space.wrap(iteratorimplementation.length())
# ____________________________________________________________
Modified: pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_dictmultiobject.py Thu Jan 4 00:47:53 2007
@@ -1,4 +1,5 @@
import autopath
+from pypy.interpreter.error import OperationError
from pypy.objspace.std.dictmultiobject import \
W_DictMultiObject, setitem__DictMulti_ANY_ANY, getitem__DictMulti_ANY, \
EmptyDictImplementation, RDictImplementation, StrDictImplementation, \
@@ -14,6 +15,20 @@
def setup_class(cls):
cls.space = gettestobjspace(**{"objspace.std.withmultidict": True})
+ def test_len_iter(self):
+ d = {1: 2, 3: 4}
+ i = iter(d)
+ assert len(i) == 2
+ x = i.next()
+ assert len(i) == 1
+ y = i.next()
+ assert len(i) == 0
+ l = [x, y]
+ l.sort()
+ assert l == [1, 3]
+ raises(StopIteration, i.next)
+ raises(StopIteration, i.next)
+
class TestW_DictSharing(test_dictobject.TestW_DictObject):
def setup_class(cls):
cls.space = gettestobjspace(**{"objspace.std.withsharingdict": True})
@@ -44,6 +59,12 @@
def isinstance(self, obj, klass):
return isinstance(obj, klass)
+ def newtuple(self, l):
+ return tuple(l)
+
+ w_StopIteration = StopIteration
+ w_None = None
+
class TestDictImplementation:
def setup_method(self,method):
self.space = FakeSpace()
@@ -124,21 +145,39 @@
def test_iterkeys(self):
self.impl.setitem(self.string, 1000)
self.impl.setitem(self.string2, 2000)
- keys = list(self.impl.iterkeys())
+ iteratorimplementation = self.impl.iterkeys()
+ keys = []
+ while 1:
+ key = iteratorimplementation.next()
+ if key is None:
+ break
+ keys.append(key)
keys.sort()
assert keys == [self.string, self.string2]
def test_itervalues(self):
self.impl.setitem(self.string, 1000)
self.impl.setitem(self.string2, 2000)
- values = list(self.impl.itervalues())
+ iteratorimplementation = self.impl.itervalues()
+ values = []
+ while 1:
+ value = iteratorimplementation.next()
+ if value is None:
+ break
+ values.append(value)
values.sort()
assert values == [1000, 2000]
def test_iteritems(self):
self.impl.setitem(self.string, 1000)
self.impl.setitem(self.string2, 2000)
- items = list(self.impl.iteritems())
+ iteratorimplementation = self.impl.iteritems()
+ items = []
+ while 1:
+ item = iteratorimplementation.next()
+ if item is None:
+ break
+ items.append(item)
items.sort()
assert items == zip([self.string, self.string2], [1000, 2000])
From arigo at codespeak.net Thu Jan 4 11:39:55 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 4 Jan 2007 11:39:55 +0100 (CET)
Subject: [pypy-svn] r36142 - pypy/extradoc/planning/secprototype
Message-ID: <20070104103955.D79B310068@code0.codespeak.net>
Author: arigo
Date: Thu Jan 4 11:39:48 2007
New Revision: 36142
Modified:
pypy/extradoc/planning/secprototype/arch-pypy-basic.png
pypy/extradoc/planning/secprototype/arch-translation.png
Log:
Crop a bit the images, removing extra white space and title
(which is already in the html page)
Modified: pypy/extradoc/planning/secprototype/arch-pypy-basic.png
==============================================================================
Binary files. No diff available.
Modified: pypy/extradoc/planning/secprototype/arch-translation.png
==============================================================================
Binary files. No diff available.
From arigo at codespeak.net Thu Jan 4 12:18:33 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 4 Jan 2007 12:18:33 +0100 (CET)
Subject: [pypy-svn] r36143 - pypy/extradoc/planning/secprototype
Message-ID: <20070104111833.4F5F610069@code0.codespeak.net>
Author: arigo
Date: Thu Jan 4 12:18:30 2007
New Revision: 36143
Modified:
pypy/extradoc/planning/secprototype/talk.txt
Log:
Tweaks to the look of the talk.
Modified: pypy/extradoc/planning/secprototype/talk.txt
==============================================================================
--- pypy/extradoc/planning/secprototype/talk.txt (original)
+++ pypy/extradoc/planning/secprototype/talk.txt Thu Jan 4 12:18:30 2007
@@ -9,19 +9,20 @@
:Authors: Samuele Pedroni, Armin Rigo
:Date: 5th January 2007
-:Location: IBM, Zuerich
+:Location: IBM, Z?rich
Outline
==============
-Part 1
-------
-PyPy introduction and architecture overview
+*Part 1*
+
+ PyPy introduction and architecture overview
+
+*Part 2*
+
+ Architecture flexibility and hooks relevant
+ to security
-Part 2
-------
-Architecture flexibility and hooks relevant
-to security
Part 1 - Architecture overview
================================
@@ -44,7 +45,7 @@
Goals (i)
======================
-An Architecture for flexibility
+An architecture for flexibility
- some decisions are invasive
and fixed in CPython (e.g.
@@ -63,11 +64,8 @@
- generate a psyco-like JIT
-(right now without a JIT
-we can be 2.3x-6x slower than
-CPython, depending on features
-etc, we can still improve on
-this too)
+currently: without a JIT, 2.3x-6x slower than
+CPython (depends on features); room for improvement
Goals (iii)
=======================
@@ -76,17 +74,20 @@
- POSIX/C (like CPython)
- .NET (like IronPython)
+- JVM (like Jython)
- ...
How
=====================
-- Python interpreter written
+We have:
+
+- a Python interpreter written
in Python, low-level details
left out (30000 LOC)
-- a subset static enough
+- a language subset static enough
to allow analysis (RPython)
-- translated to low-level targets
+- translated to low-level targets,
filling in the details (C, .NET,
...)
@@ -128,7 +129,7 @@
- library of all python types and operations on them
- encapsulates all knowledge about app-level objects
- is not concerned with control flow or bytecode
-- e.g. enough control to implement lazy evaluation
+- e.g. enough control to implement lazy evaluation (more later)
Builtin and Fundamental Modules
===============================
@@ -144,8 +145,6 @@
.. image:: arch-translation.png
:align: center
- :width: 500
- :height: 500
Translation Aspects
====================
@@ -159,6 +158,11 @@
Part 2
===============
+.. empty, just to mark the transition
+
+Part 2
+===============
+
Architecture flexibility and hooks relevant
to security:
@@ -168,25 +172,31 @@
Proxy Spaces
=================
-- *Object spaces* implement all semantic operations
+- An object space implements all semantic operations
of the language
- Interface: one method per operation, e.g. ``add(x, y)``
-- It is possible to uniformly control all
- operations by wrapping the *standard object
- space* in a proxy space
+- we can uniformly control all
+ operations by wrapping the "standard object
+ space" in a proxy space
Thunk Space
=================
-- Provides lazy evaluation::
+- Provides lazy evaluation:
- x = thunk(f, 42)
- ...
- print x+1 # f(42) only called here
+ +--------------------------------------------------+
+ | |
+ | ``x = thunk(f, 42)`` |
+ | |
+ | ... |
+ | |
+ | ``print x + 1`` *# calls f(42)* |
+ | |
+ +--------------------------------------------------+
-- The proxy *thunk space* generically implements the policy
+- The proxy **thunk space** generically implements the policy
of forcing lazy objects before they are operated on
Thunk Space (2)
@@ -205,16 +215,23 @@
Taint Space
=================
-- Provides tainted objects::
+- Provides tainted objects:
- y = taint(x)
- ...
- z = y + 1
- print untaint(z, expected_type)
+ +--------------------------------------------------+
+ | |
+ | ``y = taint(x)`` |
+ | |
+ | ... |
+ | |
+ | ``z = y + 1`` |
+ | |
+ | ``print untaint(z, expected_type)`` |
+ | |
+ +--------------------------------------------------+
-- tainted objects are boxes around regular objects
+- tainted objects: boxes around regular objects
-- operations propagate taintedness (z above is tainted too)
+- operations propagate taintedness (``z`` above is tainted too)
Taint Space (2)
==================
@@ -262,5 +279,6 @@
for which we have no special framework support so far; also,
Python is not suited to compile more than one module at a time)
+
.. |bullet| unicode:: U+02022
-.. footer:: Samuele Pedroni, Armin Rigo, PyPy Team |bullet| IBM Zuerich |bullet| 5th January 2007
+.. footer:: Samuele Pedroni, Armin Rigo, PyPy Team |bullet| IBM Z?rich |bullet| 5th January 2007 |bullet| ``http://codespeak.net/pypy``
From arigo at codespeak.net Thu Jan 4 12:50:46 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 4 Jan 2007 12:50:46 +0100 (CET)
Subject: [pypy-svn] r36144 - pypy/dist/pypy/interpreter
Message-ID: <20070104115046.69D3E10070@code0.codespeak.net>
Author: arigo
Date: Thu Jan 4 12:50:42 2007
New Revision: 36144
Modified:
pypy/dist/pypy/interpreter/gateway.py
Log:
Try to avoid a race condition when writing files to the _cache
directory.
Modified: pypy/dist/pypy/interpreter/gateway.py
==============================================================================
--- pypy/dist/pypy/interpreter/gateway.py (original)
+++ pypy/dist/pypy/interpreter/gateway.py Thu Jan 4 12:50:42 2007
@@ -853,7 +853,7 @@
initfunc, newsrc = translate_as_module(
self.code, self.filename, self.modname)
fname = cls.cache_path.join(name+".py").strpath
- f = file(fname, "w")
+ f = file(get_tmp_file_name(fname), "w")
print >> f, """\
# self-destruct on double-click:
if __name__ == "__main__":
@@ -870,6 +870,7 @@
print >> f, "from pypy._cache import known_code"
print >> f, "known_code[%r] = %s" % (key, initfunc.__name__)
f.close()
+ rename_tmp_to_eventual_file_name(fname)
w_glob = initfunc(space)
return w_glob
build_applevelinterp_dict = classmethod(build_applevelinterp_dict)
@@ -897,7 +898,7 @@
try:
pth.remove()
except: pass
- f = file(str(ini), "w")
+ f = file(get_tmp_file_name(str(ini)), "w")
f.write("""\
# This folder acts as a cache for code snippets which have been
# compiled by compile_as_module().
@@ -931,11 +932,37 @@
del harakiri
""" % GI_VERSION)
f.close()
+ rename_tmp_to_eventual_file_name(str(ini))
import pypy._cache
cls.known_code = pypy._cache.known_code
cls._setup_done = True
_setup = classmethod(_setup)
+
+def gethostname(_cache=[]):
+ if not _cache:
+ try:
+ import socket
+ hostname = socket.gethostname()
+ except:
+ hostname = ''
+ _cache.append(hostname)
+ return _cache[0]
+
+def get_tmp_file_name(fname):
+ return '%s~%s~%d' % (fname, gethostname(), os.getpid())
+
+def rename_tmp_to_eventual_file_name(fname):
+ # generated files are first written to the host- and process-specific
+ # file 'tmpname', and then atomically moved to their final 'fname'
+ # to avoid problems if py.py is started several times in parallel
+ tmpname = get_tmp_file_name(fname)
+ try:
+ os.rename(tmpname, fname)
+ except (OSError, IOError):
+ os.unlink(fname) # necessary on Windows
+ os.rename(tmpname, fname)
+
# ____________________________________________________________
def appdef(source, applevel=ApplevelClass):
From mwh at codespeak.net Thu Jan 4 13:01:57 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Thu, 4 Jan 2007 13:01:57 +0100 (CET)
Subject: [pypy-svn] r36145 - pypy/dist/pypy/translator/benchmark
Message-ID: <20070104120157.46E8810071@code0.codespeak.net>
Author: mwh
Date: Thu Jan 4 13:01:52 2007
New Revision: 36145
Added:
pypy/dist/pypy/translator/benchmark/benchmarks.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/benchmark/bench-custom.py
Log:
sundry improvements to bench-custom and related stuff:
move benchmark definitions to a separate file
allow benchmarks to run when not run from the goal directory.
Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/bench-custom.py (original)
+++ pypy/dist/pypy/translator/benchmark/bench-custom.py Thu Jan 4 13:01:52 2007
@@ -2,69 +2,23 @@
import autopath
from pypy.translator.benchmark.result import BenchmarkResult
+from pypy.translator.benchmark.benchmarks import BENCHMARKS
import os, sys, time, pickle, re
-PYSTONE_CMD = 'from test import pystone;pystone.main(%s)'
-PYSTONE_PATTERN = 'This machine benchmarks at'
-PYSTONE_ASCENDING_GOOD = True
-
-RICHARDS_CMD = 'from richards import *;main(iterations=%d)'
-RICHARDS_PATTERN = 'Average time per iteration:'
-RICHARDS_ASCENDING_GOOD = False
-
-def get_result(txt, pattern):
- for line in txt.split('\n'):
- if line.startswith(pattern):
- break
- else:
- print 'warning: this is not valid output'
- return 99999.0
- return float(line.split()[len(pattern.split())])
-
-def run_cmd(cmd):
- #print "running", cmd
- pipe = os.popen(cmd + ' 2>&1')
- return pipe.read()
-
-def run_pystone(executable='/usr/local/bin/python', n=0):
- argstr = PYSTONE_CMD % (str(n) and n or '')
- txt = run_cmd('"%s" -c "%s"' % (executable, argstr))
- return get_result(txt, PYSTONE_PATTERN)
-
-def run_richards(executable='/usr/local/bin/python', n=5):
- argstr = RICHARDS_CMD % n
- txt = run_cmd('"%s" -c "%s"' % (executable, argstr))
- return get_result(txt, RICHARDS_PATTERN)
-
-def run_translate(executable='/usr/local/bin/python'):
- argstr = 'sh -c "time %s translate.py --text --batch --backendopt --no-compile targetrpystonedalone.py > /dev/null 2>/dev/null" 2>&1 | grep real'
- txt = run_cmd(argstr%executable)
- m = re.match('real\s+(?P\\d+)m(?P\\d+\\.\\d+)s', txt)
- if not m:
- print repr(txt)
- print 'ow'
- return 99999.0
- return 1000*(float(m.group('mins'))*60 + float(m.group('secs')))
-
-BENCHMARKS = [('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'),
- ('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''),
- ('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'),
- ]
+def get_executables(args): #sorted by revision number (highest first)
+ return sorted(args, key=os.path.getmtime)
-def get_executables(): #sorted by revision number (highest first)
- return sorted(sys.argv[1:], key=os.path.getmtime)
-
-def main():
+def main(options, args):
benchmark_result = BenchmarkResult('bench-custom.benchmark_result')
- ref_rich, ref_stone = None, None
+ benchmarks = [b for b in BENCHMARKS if b[0] in options.benchmarks]
- exes = get_executables()
+ exes = get_executables(args)
pythons = 'python2.4 python2.3'.split()
width = max(map(len, exes+pythons+['executable'])) + 3
print 'date size codesize %-*s'%(width, 'executable'),
- for name, run, ascgood, units in BENCHMARKS:
+ for name, run, ascgood, units in benchmarks:
print ' %-*s'%(6+len(units)+2+8+2-4, name),
print
sys.stdout.flush()
@@ -84,7 +38,7 @@
exe_ = './' + exe
print '%-26s %8s %8s %-*s'%(ctime, size, codesize, width, exe),
sys.stdout.flush()
- for name, run, ascgood, units in BENCHMARKS:
+ for name, run, ascgood, units in benchmarks:
n = exe + '_' + name
if not benchmark_result.is_stable(n):
benchmark_result.update(n, run(exe_), ascgood)
@@ -101,4 +55,11 @@
sys.stdout.flush()
if __name__ == '__main__':
- main()
+ from optparse import OptionParser
+ parser = OptionParser()
+ parser.add_option(
+ '--benchmarks', dest='benchmarks',
+ default=','.join([b[0] for b in BENCHMARKS])
+ )
+ options, args = parser.parse_args(sys.argv[1:])
+ main(options, args)
Added: pypy/dist/pypy/translator/benchmark/benchmarks.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/benchmark/benchmarks.py Thu Jan 4 13:01:52 2007
@@ -0,0 +1,56 @@
+import os, sys, time, pickle, re, py
+
+PYSTONE_CMD = 'from test import pystone;pystone.main(%s)'
+PYSTONE_PATTERN = 'This machine benchmarks at'
+PYSTONE_ASCENDING_GOOD = True
+
+RICHARDS_CMD = 'from richards import *;main(iterations=%d)'
+RICHARDS_PATTERN = 'Average time per iteration:'
+RICHARDS_ASCENDING_GOOD = False
+
+def get_result(txt, pattern):
+ for line in txt.split('\n'):
+ if line.startswith(pattern):
+ break
+ else:
+ print repr(txt)
+ print 'warning: this is not valid output'
+ return 99999.0
+ return float(line.split()[len(pattern.split())])
+
+def run_cmd(cmd):
+ #print "running", cmd
+ pipe = os.popen(cmd + ' 2>&1')
+ r = pipe.read()
+ status = pipe.close()
+ if status:
+ print "warning: %r had exit status %s"%(cmd, status)
+ return r
+
+def run_pystone(executable='/usr/local/bin/python', n=''):
+ distdir = py.magic.autopath().dirpath().dirpath().dirpath().dirpath()
+ pystone = distdir.join('lib-python').join('2.4.1').join('test').join('pystone.py')
+ txt = run_cmd('"%s" "%s" %s' % (executable, pystone, n))
+ return get_result(txt, PYSTONE_PATTERN)
+
+def run_richards(executable='/usr/local/bin/python', n=5):
+ richards = py.magic.autopath().dirpath().dirpath().join('goal').join('richards.py')
+ txt = run_cmd('"%s" %s %s' % (executable, richards, n))
+ return get_result(txt, RICHARDS_PATTERN)
+
+def run_translate(executable='/usr/local/bin/python'):
+ translate = py.magic.autopath().dirpath().dirpath().join('goal').join('translate.py')
+ argstr = 'sh -c "time %s %s --text --batch --backendopt --no-compile targetrpystonedalone.py > /dev/null 2>/dev/null" 2>&1 | grep real'
+ cmd = argstr%(executable, translate)
+ txt = run_cmd(cmd)
+ m = re.match('real\s+(?P\\d+)m(?P\\d+\\.\\d+)s', txt)
+ if not m:
+ print repr(txt)
+ print 'ow'
+ return 99999.0
+ return 1000*(float(m.group('mins'))*60 + float(m.group('secs')))
+
+BENCHMARKS = [('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'),
+ ('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''),
+ ('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'),
+ ]
From arigo at codespeak.net Thu Jan 4 13:19:20 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 4 Jan 2007 13:19:20 +0100 (CET)
Subject: [pypy-svn] r36146 - pypy/dist/pypy/translator/llvm
Message-ID: <20070104121920.4BF1D10071@code0.codespeak.net>
Author: arigo
Date: Thu Jan 4 13:19:18 2007
New Revision: 36146
Modified:
pypy/dist/pypy/translator/llvm/database.py
Log:
Fix the repr_address().
Modified: pypy/dist/pypy/translator/llvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/database.py (original)
+++ pypy/dist/pypy/translator/llvm/database.py Thu Jan 4 13:19:18 2007
@@ -467,10 +467,9 @@
def repr_address(self, type_, value):
if not value:
return 'null'
- obj = value.ptr._obj
- typename = self.database.repr_type(lltype.typeOf(obj))
- ref = self.database.repr_name(obj)
- res = "cast(%s* %s to sbyte*)" % (typename, ref)
+ ptr = value.ptr
+ node, ref = self.database.repr_constant(ptr)
+ res = "cast(%s to sbyte*)" % (ref,)
return res
def repr_weakgcaddress(self, type_, value):
From arigo at codespeak.net Thu Jan 4 14:29:00 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 4 Jan 2007 14:29:00 +0100 (CET)
Subject: [pypy-svn] r36147 - pypy/dist/pypy/rlib/rctypes
Message-ID: <20070104132900.B50F010069@code0.codespeak.net>
Author: arigo
Date: Thu Jan 4 14:28:58 2007
New Revision: 36147
Modified:
pypy/dist/pypy/rlib/rctypes/implementation.py
pypy/dist/pypy/rlib/rctypes/rctypesobject.py
pypy/dist/pypy/rlib/rctypes/rpointer.py
Log:
Fixes to the forward pointer code.
Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py Thu Jan 4 14:28:58 2007
@@ -132,12 +132,14 @@
else:
# non-recursive case
TLS.pending = []
- controller = cls(ctype)
- pending = TLS.pending
- del TLS.pending
- pending.append(controller)
- for c1 in pending:
- c1.setup()
+ try:
+ controller = cls(ctype)
+ TLS.pending.append(controller)
+ finally:
+ pending = TLS.pending
+ del TLS.pending
+ for c1 in pending:
+ c1.setup()
return controller
def getcontroller(ctype):
Modified: pypy/dist/pypy/rlib/rctypes/rctypesobject.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rctypesobject.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rctypesobject.py Thu Jan 4 14:28:58 2007
@@ -294,7 +294,7 @@
return RCTypesPtr
RPointer._annspecialcase_ = 'specialize:memo'
-def _rpointer_set_pointer_type(RCTypesPtr, contentscls):
+def _rpointer_set_pointer_type(RCTypesPtr, contentscls, force=False):
assert issubclass(contentscls, RCTypesObject)
if contentscls in _abstract_classes:
raise Exception("cannot call RPointer(%s) or "
@@ -306,9 +306,10 @@
RCTypesPtr.LLTYPE.TO.become(RCTypesPtr.CONTENTS)
RCTypesPtr._OFS_ITEM = llmemory.sizeof(contentscls.LLTYPE)
RCTypesPtr.__name__ = 'RCTypes_%s' % (RCTypesPtr.LLTYPE,)
- assert not hasattr(contentscls, '_ptrcls'), (
- "the RPointer class corresponding to %r exists already" %
- (contentscls,))
+ if not force:
+ assert not hasattr(contentscls, '_ptrcls'), (
+ "the RPointer class corresponding to %r exists already" %
+ (contentscls,))
contentscls._ptrcls = RCTypesPtr
def pointer(x):
Modified: pypy/dist/pypy/rlib/rctypes/rpointer.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rpointer.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rpointer.py Thu Jan 4 14:28:58 2007
@@ -10,15 +10,19 @@
class PointerCTypeController(CTypeController):
+ ready = 0
def __init__(self, ctype):
CTypeController.__init__(self, ctype)
self.knowntype = rctypesobject.RPointer(None)
def setup(self):
- if not hasattr(self, 'contentscontroller'):
+ if self.ready == 0:
+ self.ready = 1
self.contentscontroller = getcontroller(self.ctype._type_)
- self.knowntype.setpointertype(self.contentscontroller.knowntype)
+ self.knowntype.setpointertype(self.contentscontroller.knowntype,
+ force=True)
+ self.ready = 2
def new(self, ptrto=None):
obj = self.knowntype.allocate()
From santagada at codespeak.net Thu Jan 4 16:10:03 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 4 Jan 2007 16:10:03 +0100 (CET)
Subject: [pypy-svn] r36149 - pypy/dist/pypy/lang/js
Message-ID: <20070104151003.D03D010063@code0.codespeak.net>
Author: santagada
Date: Thu Jan 4 16:10:02 2007
New Revision: 36149
Modified:
pypy/dist/pypy/lang/js/interpreter.py
Log:
code to make an interactive interpreter work
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Thu Jan 4 16:10:02 2007
@@ -43,8 +43,15 @@
def load_source(self, script_source):
"""load a source script text to the interpreter"""
temp_dict = parse(script_source)
+ #import pprint
+ #pprint.pprint(temp_dict)
self.script = from_dict(temp_dict)
+ def append_source(self, script_source):
+ temp_dict = parse(script_source)
+ newscript = from_dict(temp_dict)
+ self.script.append_script(newscript)
+
def run(self):
"""run the interpreter"""
return self.script.call(self.global_context)
@@ -359,18 +366,26 @@
except ExecutionReturned, e:
return e.value
+ def append_script(self, newscript):
+ """copy everything from the newscript to this one"""
+ self.var_decl.extend(newscript.var_decl)
+ self.nodes.extend(newscript.nodes)
+ self.func_decl.extend(newscript.func_decl)
+
class Semicolon(Node):
- def __init__(self, expr):
+ def __init__(self, expr = None):
self.expr = expr
- def call(self, ctx=None):
+ def call(self, ctx):
+ if self.expr is None:
+ return
return self.expr.call(ctx)
class String(Node):
def __init__(self, strval):
self.strval = strval
- def call(self, ctx=None):
+ def call(self, ctx):
return W_String(self.strval)
def get_literal(self):
@@ -556,6 +571,8 @@
var_decl = [from_dict(x) for x in d['varDecls']]
return Script(getlist(d), var_decl, func_decl)
elif tp == 'SEMICOLON':
+ if d['expression'] == 'null':
+ return Semicolon()
return Semicolon(from_dict(d['expression']))
elif tp == 'STRING':
return String(d['value'])
From santagada at codespeak.net Thu Jan 4 16:12:49 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 4 Jan 2007 16:12:49 +0100 (CET)
Subject: [pypy-svn] r36150 - pypy/dist/pypy/lang/js/test
Message-ID: <20070104151249.E60C410063@code0.codespeak.net>
Author: santagada
Date: Thu Jan 4 16:12:48 2007
New Revision: 36150
Added:
pypy/dist/pypy/lang/js/test/autotestbase.py
Log:
code to use the mozilla-py.test translator
Added: pypy/dist/pypy/lang/js/test/autotestbase.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lang/js/test/autotestbase.py Thu Jan 4 16:12:48 2007
@@ -0,0 +1,17 @@
+# encoding: utf-8
+"""
+autotestbase.py
+"""
+
+from pypy.lang.js import interpreter
+
+class TestCase(object):
+ code = None
+ def setup_class(self):
+ self.inter = interpreter.Interpreter(self.code or ";")
+
+ def auto(self, expect, typeof, code):
+ self.inter.append_source(code)
+ r = self.inter.run()
+ assert r.GetValue().ToString() == expect
+ # TODO: assert typeof
From mwh at codespeak.net Thu Jan 4 17:25:48 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Thu, 4 Jan 2007 17:25:48 +0100 (CET)
Subject: [pypy-svn] r36151 - pypy/dist/pypy/interpreter
Message-ID: <20070104162548.0A15010074@code0.codespeak.net>
Author: mwh
Date: Thu Jan 4 17:25:46 2007
New Revision: 36151
Modified:
pypy/dist/pypy/interpreter/baseobjspace.py
Log:
rewrite exception_match to be boringly similar to cpython's version -- but
twice as fast for certain microbenches, and ~5% for the usual benchmarks.
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Jan 4 17:25:46 2007
@@ -550,27 +550,15 @@
def exception_match(self, w_exc_type, w_check_class):
"""Checks if the given exception type matches 'w_check_class'."""
- check_list = [w_check_class]
- while check_list:
- w_item = check_list.pop()
- # Match identical items.
- if self.is_w(w_exc_type, w_item):
- return True
- try:
- # Match subclasses.
- if self.is_true(self.abstract_issubclass(w_exc_type, w_item, failhard=True)):
+ if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
+ exclst_w = self.unpacktuple(w_check_class)
+ for w_e in exclst_w:
+ if self.exception_match(w_exc_type, w_e):
return True
- except OperationError:
- # Assume that this is a TypeError: w_item not a type,
- # and assume that w_item is then actually a tuple.
- try:
- exclst = self.unpackiterable(w_item)
- except OperationError:
- # hum, maybe it is not a tuple after all, and w_exc_type
- # was not a type at all (string exceptions). Give up.
- continue
- check_list.extend(exclst)
- return False
+ return False
+ if self.is_true(self.abstract_issubclass(w_exc_type, w_check_class)):
+ return True
+ return self.is_w(w_exc_type, w_check_class)
def call(self, w_callable, w_args, w_kwds=None):
args = Arguments.frompacked(self, w_args, w_kwds)
From xoraxax at codespeak.net Thu Jan 4 20:35:52 2007
From: xoraxax at codespeak.net (xoraxax at codespeak.net)
Date: Thu, 4 Jan 2007 20:35:52 +0100 (CET)
Subject: [pypy-svn] r36158 - pypy/dist/pypy/interpreter
Message-ID: <20070104193552.7649810070@code0.codespeak.net>
Author: xoraxax
Date: Thu Jan 4 20:35:50 2007
New Revision: 36158
Modified:
pypy/dist/pypy/interpreter/baseobjspace.py
Log:
Speed up the exception matching even more. Compared to the last
rev, only two micro benches are slower, in total they are still
faster than before Micheal's rewrite. The fastest ones:
0.37x slower on test_dict.test_dict_setitem1()
0.62x slower on test_dict.test_dict_instance_setattr_instance_dict()
0.64x slower on test_dict.test_dict_instance_setnewattr_instance_dict()
0.67x slower on test_bltn.test_call_sin()
0.76x slower on test_dict.test_dict_raw_range()
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Thu Jan 4 20:35:50 2007
@@ -550,15 +550,17 @@
def exception_match(self, w_exc_type, w_check_class):
"""Checks if the given exception type matches 'w_check_class'."""
+ if self.is_w(w_exc_type, w_check_class):
+ return True
+ if self.is_true(self.abstract_issubclass(w_exc_type, w_check_class)):
+ return True
+
if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
exclst_w = self.unpacktuple(w_check_class)
for w_e in exclst_w:
if self.exception_match(w_exc_type, w_e):
return True
- return False
- if self.is_true(self.abstract_issubclass(w_exc_type, w_check_class)):
- return True
- return self.is_w(w_exc_type, w_check_class)
+ return False
def call(self, w_callable, w_args, w_kwds=None):
args = Arguments.frompacked(self, w_args, w_kwds)
From ericvrp at codespeak.net Fri Jan 5 20:58:57 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 5 Jan 2007 20:58:57 +0100 (CET)
Subject: [pypy-svn] r36172 - in pypy/dist/pypy/jit/codegen/llvm: . lib test
Message-ID: <20070105195857.F220810077@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 5 20:58:55 2007
New Revision: 36172
Modified:
pypy/dist/pypy/jit/codegen/llvm/compatibility.py
pypy/dist/pypy/jit/codegen/llvm/lib/libllvmjit.cpp
pypy/dist/pypy/jit/codegen/llvm/test/test_llvmjit.py
Log:
Initial support for llvm 2.x from signed/unsigned integers to signless integers.
So most jit/codegen/llvm tests currently fail with llvm 2.x (still beta)
(as does translator/llvm), this can easily be fixed in the jit codegenator case.
Modified: pypy/dist/pypy/jit/codegen/llvm/compatibility.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/compatibility.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/compatibility.py Fri Jan 5 20:58:55 2007
@@ -8,6 +8,11 @@
icmp = scmp = ucmp = fcmp = 'set'
inttoptr = trunc = zext = bitcast = 'cast'
shr_prefix = ('', '')
+ i8 = 'ubyte'
+ i16 = 'short'
+ i32 = 'int'
+ i64 = 'long'
+ define = ''
else: # >= 2.0
icmp = 'icmp '
scmp = 'icmp s'
@@ -18,3 +23,8 @@
zext = 'zext'
bitcast = 'bitcast'
shr_prefix = ('l', 'a')
+ define = 'define'
+ i8 = 'i8'
+ i16 = 'i16'
+ i32 = 'i32'
+ i64 = 'i64'
Modified: pypy/dist/pypy/jit/codegen/llvm/lib/libllvmjit.cpp
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/lib/libllvmjit.cpp (original)
+++ pypy/dist/pypy/jit/codegen/llvm/lib/libllvmjit.cpp Fri Jan 5 20:58:55 2007
@@ -211,7 +211,9 @@
args.push_back((void*)param);
GenericValue gv = gp_execution_engine->runFunction((Function*)function, args);
- return gv.IntVal;
+ //return gv.IntVal; //llvm 1.x
+ //return gv.Int32Val; //llvm 2.x
+ return *(int*)&gv; //XXX todo: figure out if there is a C define for the llvm version
}
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_llvmjit.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_llvmjit.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_llvmjit.py Fri Jan 5 20:58:55 2007
@@ -2,6 +2,7 @@
from os.path import dirname, join
from pypy.translator.c.test.test_genc import compile
from pypy.jit.codegen.llvm import llvmjit
+from pypy.jit.codegen.llvm.compatibility import define, icmp, i32
try:
from pypy.jit.codegen.llvm import llvmjit
@@ -15,95 +16,94 @@
py.test.skip('dynamic vs. static library issue on Darwin. see: http://www.cocoadev.com/index.pl?ApplicationLinkingIssues for more information (FIXME)')
#
-llsquare = '''int %square(int %n) {
- %n2 = mul int %n, %n
- ret int %n2
-}'''
-
-llmul2 = '''int %mul2(int %n) {
- %n2 = mul int %n, 2
- ret int %n2
-}'''
+llsquare = '''%(define)s %(i32)s %%square(%(i32)s %%n) {
+ %%n2 = mul %(i32)s %%n, %%n
+ ret %(i32)s %%n2
+}''' % vars()
+
+llmul2 = '''%(define)s %(i32)s %%mul2(%(i32)s %%n) {
+ %%n2 = mul %(i32)s %%n, 2
+ ret %(i32)s %%n2
+}''' % vars()
#
-llvm2 = llvmjit.llvm_version() >= 2.0
-lldeadcode = '''int %%deadcode(int %%n) {
+lldeadcode = '''%(define)s %(i32)s %%deadcode(%(i32)s %%n) {
Test:
- %%cond = %s int %%n, %%n
+ %%cond = %(icmp)seq %(i32)s %%n, %%n
br bool %%cond, label %%IfEqual, label %%IfUnequal
IfEqual:
- %%n2 = mul int %%n, 2
- ret int %%n2
+ %%n2 = mul %(i32)s %%n, 2
+ ret %(i32)s %%n2
IfUnequal:
- ret int -1
-}''' % ('seteq', 'icmp eq')[llvm2]
+ ret %(i32)s -1
+}''' % vars()
#
-llfuncA = '''int %func(int %n) {
- %n2 = add int %n, %n
- ret int %n2
-}'''
+llfuncA = '''%(define)s %(i32)s %%func(%(i32)s %%n) {
+ %%n2 = add %(i32)s %%n, %%n
+ ret %(i32)s %%n2
+}''' % vars()
-llfuncB = '''int %func(int %n) {
- %n2 = mul int %n, %n
- ret int %n2
-}'''
+llfuncB = '''%(define)s %(i32)s %%func(%(i32)s %%n) {
+ %%n2 = mul %(i32)s %%n, %%n
+ ret %(i32)s %%n2
+}''' % vars()
#
-llacross1 = '''declare int %across2(int)
+llacross1 = '''declare %(i32)s %%across2(%(i32)s)
implementation
-int %across1(int %n) {
- %n2 = mul int %n, 3
- ret int %n2
+%(define)s %(i32)s %%across1(%(i32)s %%n) {
+ %%n2 = mul %(i32)s %%n, 3
+ ret %(i32)s %%n2
}
-int %across1to2(int %n) {
- %n2 = add int %n, 5
- %n3 = call int %across2(int %n2)
- ret int %n3
-}'''
+%(define)s %(i32)s %%across1to2(%(i32)s %%n) {
+ %%n2 = add %(i32)s %%n, 5
+ %%n3 = call %(i32)s %%across2(%(i32)s %%n2)
+ ret %(i32)s %%n3
+}''' % vars()
-llacross2 = '''declare int %across1(int %dsf)
+llacross2 = '''declare %(i32)s %%across1(%(i32)s %%dsf)
implementation
-int %across2(int %n) {
- %n2 = mul int %n, 7
- ret int %n2
+%(define)s %(i32)s %%across2(%(i32)s %%n) {
+ %%n2 = mul %(i32)s %%n, 7
+ ret %(i32)s %%n2
}
-int %across2to1(int %n) {
- %n2 = add int %n, 9
- %n3 = call int %across1(int %n2)
- ret int %n3
-}'''
+%(define)s %(i32)s %%across2to1(%(i32)s %%n) {
+ %%n2 = add %(i32)s %%n, 9
+ %%n3 = call %(i32)s %%across1(%(i32)s %%n2)
+ ret %(i32)s %%n3
+}''' % vars()
#
-llglobalmul4 = '''%my_global_data = external global int
+llglobalmul4 = '''%%my_global_data = external global %(i32)s
implementation
-int %globalmul4(int %a) {
- %v0 = load int* %my_global_data
- %v1 = mul int %v0, 4
- %v2 = add int %v1, %a
- store int %v2, int* %my_global_data
- ret int %v2
-}'''
+%(define)s %(i32)s %%globalmul4(%(i32)s %%a) {
+ %%v0 = load %(i32)s* %%my_global_data
+ %%v1 = mul %(i32)s %%v0, 4
+ %%v2 = add %(i32)s %%v1, %%a
+ store %(i32)s %%v2, %(i32)s* %%my_global_data
+ ret %(i32)s %%v2
+}''' % vars()
#
-llcall_global_function = '''declare int %my_global_function(int, int, int)
+llcall_global_function = '''declare %(i32)s %%my_global_function(%(i32)s, %(i32)s, %(i32)s)
implementation
-int %call_global_function(int %n) {
- %v = call int %my_global_function(int 3, int %n, int 7) ;note: maybe tail call?
- ret int %v
-}'''
+%(define)s %(i32)s %%call_global_function(%(i32)s %%n) {
+ %%v = call %(i32)s %%my_global_function(%(i32)s 3, %(i32)s %%n, %(i32)s 7) ;note: maybe tail call?
+ ret %(i32)s %%v
+}''' % vars()
#helpers
def execute(llsource, function_name, param):
From xoraxax at codespeak.net Sat Jan 6 16:13:56 2007
From: xoraxax at codespeak.net (xoraxax at codespeak.net)
Date: Sat, 6 Jan 2007 16:13:56 +0100 (CET)
Subject: [pypy-svn] r36177 - pypy/dist/pypy/interpreter
Message-ID: <20070106151356.5C13B10075@code0.codespeak.net>
Author: xoraxax
Date: Sat Jan 6 16:13:55 2007
New Revision: 36177
Modified:
pypy/dist/pypy/interpreter/baseobjspace.py
Log:
Oops, cleaned a few tabs.
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Sat Jan 6 16:13:55 2007
@@ -550,10 +550,10 @@
def exception_match(self, w_exc_type, w_check_class):
"""Checks if the given exception type matches 'w_check_class'."""
- if self.is_w(w_exc_type, w_check_class):
- return True
- if self.is_true(self.abstract_issubclass(w_exc_type, w_check_class)):
- return True
+ if self.is_w(w_exc_type, w_check_class):
+ return True
+ if self.is_true(self.abstract_issubclass(w_exc_type, w_check_class)):
+ return True
if self.is_true(self.isinstance(w_check_class, self.w_tuple)):
exclst_w = self.unpacktuple(w_check_class)
From ericvrp at codespeak.net Sat Jan 6 17:43:33 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 6 Jan 2007 17:43:33 +0100 (CET)
Subject: [pypy-svn] r36178 - pypy/dist/pypy/jit/codegen/llvm
Message-ID: <20070106164333.8206B10078@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 6 17:43:31 2007
New Revision: 36178
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
Log:
Remaining changes to keep jit/codegen/llvm llvm 2.x compatible.
(signed/unsigned -> signless integers)
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Sat Jan 6 17:43:31 2007
@@ -8,7 +8,7 @@
from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr
from pypy.jit.codegen.llvm.conftest import option
from pypy.jit.codegen.llvm.compatibility import icmp, scmp, ucmp, fcmp, inttoptr,\
- trunc, zext, bitcast, shr_prefix
+ trunc, zext, bitcast, shr_prefix, define, i8, i16, i32
LINENO = option.lineno
@@ -89,7 +89,7 @@
def __init__(self, type):
self.n = count.n_vars
self.type = type
- self.signed = type is 'int' or type is 'float'
+ self.signed = type is i32 or type is 'float'
count.n_vars += 1
def operand(self):
@@ -130,7 +130,7 @@
class CharConst(GenericConst):
- type = 'ubyte'
+ type = i8
signed = False
def __init__(self, value):
@@ -142,7 +142,7 @@
class UniCharConst(GenericConst):
- type = 'int'
+ type = i32
signed = True
def __init__(self, value):
@@ -150,7 +150,7 @@
class IntConst(GenericConst):
- type = 'int'
+ type = i32
signed = True
def __init__(self, value):
@@ -165,7 +165,7 @@
class UIntConst(GenericConst):
- type = 'uint'
+ type = i32 #'uint'
signed = False
def __init__(self, value):
@@ -181,7 +181,7 @@
class AddrConst(GenConst):
- type = 'int*'
+ type = i32 + '*'
signed = False
def __init__(self, addr):
@@ -277,7 +277,8 @@
def writecode(self, lines):
argtypes, restype = self.sigtoken
- lines.append('%s %%%s(%s){' % (
+ lines.append('%s %s %%%s(%s){' % (
+ define,
restype,
self.name,
','.join([v.operand() for v in self.inputargs])))
@@ -385,21 +386,21 @@
def op_int_xor(self, gv_x, gv_y): return self._rgenop2_generic('xor' , gv_x, gv_y)
def op_int_lshift(self, gv_x, gv_y):
- gv_y_ubyte = Var('ubyte')
- self.asm.append(' %s=%s %s to ubyte' % (
- gv_y_ubyte.operand2(), trunc, gv_y.operand()))
+ gv_y_i8 = Var(i8)
+ self.asm.append(' %s=%s %s to %s' % (
+ gv_y_i8.operand2(), trunc, gv_y.operand(), i8))
gv_result = Var(gv_x.type)
self.asm.append(' %s=shl %s,%s' % (
- gv_result.operand2(), gv_x.operand(), gv_y_ubyte.operand()))
+ gv_result.operand2(), gv_x.operand(), gv_y_i8.operand()))
return gv_result
def op_int_rshift(self, gv_x, gv_y):
- gv_y_ubyte = Var('ubyte')
- self.asm.append(' %s=%s %s to ubyte' % (
- gv_y_ubyte.operand2(), trunc, gv_y.operand()))
+ gv_y_i8 = Var(i8)
+ self.asm.append(' %s=%s %s to %s' % (
+ gv_y_i8.operand2(), trunc, gv_y.operand(), i8))
gv_result = Var(gv_x.type)
self.asm.append(' %s=%sshr %s,%s' % (
- gv_result.operand2(), shr_prefix[gv_x.signed], gv_x.operand(), gv_y_ubyte.operand()))
+ gv_result.operand2(), shr_prefix[gv_x.signed], gv_x.operand(), gv_y_i8.operand()))
return gv_result
op_uint_add = op_float_add = op_int_add
@@ -537,17 +538,17 @@
return gv_result
def _cast_to_bool(self, gv_x): return self._cast_to(gv_x, 'bool')
- def _cast_to_char(self, gv_x): return self._cast_to(gv_x, 'ubyte')
- def _cast_to_unichar(self, gv_x): return self._cast_to(gv_x, 'int')
- def _cast_to_int(self, gv_x): return self._cast_to(gv_x, 'int')
- def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, 'uint')
+ def _cast_to_char(self, gv_x): return self._cast_to(gv_x, i8)
+ def _cast_to_unichar(self, gv_x): return self._cast_to(gv_x, i32)
+ def _cast_to_int(self, gv_x): return self._cast_to(gv_x, i32)
+ def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, i32) #'uint')
def _cast_to_float(self, gv_x): return self._cast_to(gv_x, 'float')
def _trunc_to_bool(self, gv_x): return self._trunc_to(gv_x, 'bool')
- def _trunc_to_char(self, gv_x): return self._trunc_to(gv_x, 'ubyte')
- def _trunc_to_unichar(self, gv_x): return self._trunc_to(gv_x, 'int')
- def _trunc_to_int(self, gv_x): return self._trunc_to(gv_x, 'int')
- def _trunc_to_uint(self, gv_x): return self._trunc_to(gv_x, 'uint')
+ def _trunc_to_char(self, gv_x): return self._trunc_to(gv_x, i8)
+ def _trunc_to_unichar(self, gv_x): return self._trunc_to(gv_x, i32)
+ def _trunc_to_int(self, gv_x): return self._trunc_to(gv_x, i32)
+ def _trunc_to_uint(self, gv_x): return self._trunc_to(gv_x, i32) #'uint')
def _trunc_to_float(self, gv_x): return self._trunc_to(gv_x, 'float')
op_cast_char_to_bool = _trunc_to_bool
@@ -661,20 +662,20 @@
log('%s Builder.genop_getfield (%d,%d) %s' % (
self.block.label, offset, fieldsize, gv_ptr.operand()))
if fieldsize == WORD:
- t = 'int'
+ t = i32
else:
if fieldsize == 1:
- t = 'ubyte'
+ t = i8
else:
if fieldsize != 2:
logger.dump('assert fails on: fieldsize != [124]')
self.rgenop._dump_partial_lines()
assert fieldsize == 2
- t = 'short'
+ t = i16
gv_ptr_var = self._as_var(gv_ptr)
gv_p = Var(t + '*')
- self.asm.append(' %s=getelementptr %s,int %s' % (
- gv_p.operand2(), gv_ptr_var.operand(), offset / fieldsize))
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, offset / fieldsize))
gv_result = Var(t)
self.asm.append(' %s=load %s' % (
gv_result.operand2(), gv_p.operand()))
@@ -684,17 +685,17 @@
log('%s Builder.genop_setfield (%d,%d) %s=%s' % (
self.block.label, offset, fieldsize, gv_ptr.operand(), gv_value.operand()))
#if fieldsize == WORD:
- # gv_result = Var('int')
+ # gv_result = Var(i32)
#else:
# if fieldsize == 1:
- # gv_result = Var('ubyte')
+ # gv_result = Var(i8)
# else:
# assert fieldsize == 2
- # gv_result = Var('short')
+ # gv_result = Var(i16)
gv_ptr_var = self._as_var(gv_ptr)
gv_p = Var(gv_value.type+'*')
- self.asm.append(' %s=getelementptr %s,int %s' % (
- gv_p.operand2(), gv_ptr_var.operand(), offset / fieldsize))
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, offset / fieldsize))
self.asm.append(' store %s,%s' % (
gv_value.operand(), gv_p.operand()))
@@ -739,11 +740,11 @@
'''
#XXX TODO
array_length_offset, array_items_offset, itemsize = arraytoken
- gv_result = Var('int')
+ gv_result = Var(i32)
log('%s Builder.genop_getarraysubstruct %s,%s,%s' % (
self.block.label, arraytoken, gv_ptr, gv_index))
- self.asm.append(' %s=int 0 ;%s Builder.genop_getarraysubstruct %s,%s,%s' % (
- gv_result.operand2(), self.block.label, arraytoken, gv_ptr, gv_index))
+ self.asm.append(' %s=%s 0 ;%s Builder.genop_getarraysubstruct %s,%s,%s' % (
+ gv_result.operand2(), gv_result.type, self.block.label, arraytoken, gv_ptr, gv_index))
return gv_result
def genop_getarraysize(self, arraytoken, gv_ptr):
@@ -754,19 +755,19 @@
'''
#XXX TODO
array_length_offset, array_items_offset, itemsize = arraytoken
- gv_result = Var('int')
+ gv_result = Var(i32)
log('%s Builder.genop_getarraysize %s,%s' % (
self.block.label, arraytoken, gv_ptr))
- self.asm.append(' %s=int 0 ;%s Builder.genop_getarraysize %s,%s' % (
- gv_result.operand2(), self.block.label, arraytoken, gv_ptr))
+ self.asm.append(' %s=%s 0 ;%s Builder.genop_getarraysize %s,%s' % (
+ gv_result.operand2(), gv_result.type, self.block.label, arraytoken, gv_ptr))
return gv_result
def _as_var(self, gv):
if gv.is_const:
gv_var = Var(gv.type)
#XXX provide correct cast here
- self.asm.append(' %s=%s int %s to %s' % (
- gv_var.operand2(), inttoptr, gv.operand2(), gv_var.type))
+ self.asm.append(' %s=%s %s %s to %s' % (
+ gv_var.operand2(), inttoptr, i32, gv.operand2(), gv_var.type))
return gv_var
return gv
@@ -780,7 +781,7 @@
except TypeError:
offset = 4 #XXX (get inspired by ppc backend)
gv_i = Var(gv_index.type)
- self.asm.append(' %s=add %s,%d' % (
+ self.asm.append(' %s=add %s,%d ;;;;' % (
gv_i.operand2(), gv_index.operand(), offset)) #/itemsize correct?
gv_ptr_var = self._as_var(gv_ptr)
@@ -793,23 +794,27 @@
def genop_malloc_fixedsize(self, size):
log('%s Builder.genop_malloc_fixedsize %s' % (
self.block.label, str(size)))
- gv_result = Var('ubyte*') #XXX or opaque* ???
- gv_gc_malloc_fnaddr = Var('%s (int)*' % gv_result.type)
+ t = i8 + '*' #XXX or opaque* ?
+ gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
+ gv_result = Var(t)
#XXX or use addGlobalFunctionMapping in libllvmjit.restart()
- self.asm.append(' %s=%s int %d to %s ;gc_malloc_fnaddr' % (
- gv_gc_malloc_fnaddr.operand2(), inttoptr, gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
- self.asm.append(' %s=call %s(int %d)' % (
- gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), size))
+ self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr' % (
+ gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
+ gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
+ self.asm.append(' %s=call %s(%s %d)' % (
+ gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), i32, size))
return gv_result
def genop_malloc_varsize(self, varsizealloctoken, gv_size):
log('%s Builder.genop_malloc_varsize %s,%s' % (
self.block.label, varsizealloctoken, gv_size.operand()))
- gv_result = Var('ubyte*') #XXX or opaque* ???
- gv_gc_malloc_fnaddr = Var('%s (int)*' % gv_result.type)
+ t = i8 + '*' #XXX or opaque* ?
+ gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
+ gv_result = Var(t)
#XXX or use addGlobalFunctionMapping in libllvmjit.restart()
- self.asm.append(' %s=%s int %d to %s ;gc_malloc_fnaddr' % (
- gv_gc_malloc_fnaddr.operand2(), inttoptr, gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
+ self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr (varsize)' % (
+ gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
+ gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
self.asm.append(' %s=call %s(%s)' % (
gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), gv_size.operand()))
#XXX TODO set length field
@@ -957,19 +962,19 @@
# turn the type T into the llvm approximation that we'll use here
# XXX incomplete
if isinstance(T, lltype.Ptr):
- return 'int*'
+ return i32 + '*' #or opaque* ?
elif T is llmemory.Address:
- return 'int*'
+ return i32 + '*' #or apaque* ?
if T is lltype.Bool:
return 'bool'
elif T is lltype.Char:
- return 'ubyte'
+ return i8
elif T is lltype.Unsigned:
- return 'uint'
+ return i32 #'uint'
elif T is lltype.Float:
return 'float'
else:
- return 'int' #Signed/UniChar/Void
+ return i32 #Signed/UniChar/Void
@staticmethod
@specialize.memo()
From ericvrp at codespeak.net Sat Jan 6 17:56:02 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 6 Jan 2007 17:56:02 +0100 (CET)
Subject: [pypy-svn] r36179 - pypy/dist/pypy/jit/codegen/llvm/test
Message-ID: <20070106165602.C9F2110076@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 6 17:56:00 2007
New Revision: 36179
Modified:
pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
Log:
Skip this test on llvm 1.x (for now)
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py Sat Jan 6 17:56:00 2007
@@ -24,6 +24,7 @@
if llvm_version() < 2.0:
test_float_arithmetic = skip_too_minimal #segfault
+ test_unsigned = skip_too_minimal #uint_invert uses incorrect xor constant?
test_float_pow = skip
test_unichar_array = skip
From cfbolz at codespeak.net Mon Jan 8 10:28:49 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 10:28:49 +0100 (CET)
Subject: [pypy-svn] r36223 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070108092849.AD29310075@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 10:28:48 2007
New Revision: 36223
Added:
pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
Log:
planning for today
Added: pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
==============================================================================
--- (empty file)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt Mon Jan 8 10:28:48 2007
@@ -0,0 +1,108 @@
+People
+======
+
+ * Antonio
+ * Leonardo
+ * Holger
+ * Guido
+ * Maciek
+ * Armin
+ * Michael
+ * Arre
+ * Samuele
+ * Carl Friedrich
+
+later
+-----
+
+ * Laura
+ * Jacob
+ * Alexandre
+ * Sylvain
+ * Niko
+ * Eric
+
+Tasks
+=====
+
+
+
+JIT
+---
+
+* "virtual frames"
+
+ - write a small interpreter that shows the performance problems without having
+ to use the full pypy
+
+ - actually implement support for this in the rtyper and the jit...
+
+* have register allocation
+
+(Michael, Armin, Arre, Samuele)
+
+
+py.test and the py-lib
+----------------------
+
+* polish the code and documentation of the py lib, and eventually
+ release it (Holger and Maciek to investigate)
+
+* integrate api-doc and source-viewer on the py-lib web-page
+
+* use source-viewer on more code? pypy?
+
+* provide code search facility
+
+
+
+interpreter prototypes
+----------------------
+
+* discuss the status of the various prototypes (coordinated by arre?)
+
+* think especially hard about persistence
+
+* discuss fallback possibilities if py.execnet cannot run on pypy-c
+
+* (maybe try the taint object space on a cgi example + write some docs?)
+
+
+Integration and Configuration
+-----------------------------
+
+* actually use the build tool during the sprint (Guido, Carl Friedrich)
+
+* think about py-lib and pypy debian packaging
+
+* document in some detail the configuration
+
+* integrate wp9, wp10 work?
+
+* web frontend on the build tool
+
+Other
+-----
+
+* progress on the JavaScript interpreter (Leonardo, Antonio)
+
+* Java backend
+
+* discuss refinement interface for external functions
+
+* (make py-lib run on pypy-c)
+
+
+Discussions during the sprint
+=============================
+
+* status of wp6 and wp12
+
+* wp9 + wp10 + wp11 discussion
+
+* eu-report meeting
+
+* pycon talk discussion
+
+* release plannings
+
From guido at codespeak.net Mon Jan 8 10:50:21 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 10:50:21 +0100 (CET)
Subject: [pypy-svn] r36226 - pypy/dist/pypy/tool/build
Message-ID: <20070108095021.B057110076@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 10:50:13 2007
New Revision: 36226
Modified:
pypy/dist/pypy/tool/build/config.py
Log:
Updated config values for codespeak.net.
Modified: pypy/dist/pypy/tool/build/config.py
==============================================================================
--- pypy/dist/pypy/tool/build/config.py (original)
+++ pypy/dist/pypy/tool/build/config.py Mon Jan 8 10:50:13 2007
@@ -3,7 +3,7 @@
packageparent = py.magic.autopath().dirpath().dirpath().dirpath().dirpath()
# general settings, used by both server and client
-server = 'localhost'
+server = 'codespeak.net'
port = 12321
testport = 32123
path = [str(packageparent)]
From cfbolz at codespeak.net Mon Jan 8 10:56:13 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 10:56:13 +0100 (CET)
Subject: [pypy-svn] r36227 - in pypy/dist/pypy/tool/build: . bin
Message-ID: <20070108095613.33B1D10075@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 10:56:09 2007
New Revision: 36227
Added:
pypy/dist/pypy/tool/build/autopath.py
- copied unchanged from r36226, pypy/dist/pypy/tool/autopath.py
Modified:
pypy/dist/pypy/tool/build/bin/client
pypy/dist/pypy/tool/build/bin/server
pypy/dist/pypy/tool/build/bin/startcompile
Log:
add autopath imports
Modified: pypy/dist/pypy/tool/build/bin/client
==============================================================================
--- pypy/dist/pypy/tool/build/bin/client (original)
+++ pypy/dist/pypy/tool/build/bin/client Mon Jan 8 10:56:09 2007
@@ -1,5 +1,6 @@
#!/usr/bin/python
+import autopath
import py
from py.execnet import PopenGateway
from pypy.tool.build import outputbuffer
Modified: pypy/dist/pypy/tool/build/bin/server
==============================================================================
--- pypy/dist/pypy/tool/build/bin/server (original)
+++ pypy/dist/pypy/tool/build/bin/server Mon Jan 8 10:56:09 2007
@@ -1,5 +1,6 @@
#!/usr/bin/python
+import autopath
import path
from pypy.tool.build import config
Modified: pypy/dist/pypy/tool/build/bin/startcompile
==============================================================================
--- pypy/dist/pypy/tool/build/bin/startcompile (original)
+++ pypy/dist/pypy/tool/build/bin/startcompile Mon Jan 8 10:56:09 2007
@@ -1,5 +1,6 @@
#!/usr/bin/python
+import autopath
import path
import sys
import random
From cfbolz at codespeak.net Mon Jan 8 10:59:31 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 10:59:31 +0100 (CET)
Subject: [pypy-svn] r36228 - pypy/dist/pypy/tool/build
Message-ID: <20070108095931.790F510079@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 10:59:30 2007
New Revision: 36228
Modified:
pypy/dist/pypy/tool/build/client.py
Log:
(guido, cfbolz): print a message what the password-entering is about
Modified: pypy/dist/pypy/tool/build/client.py
==============================================================================
--- pypy/dist/pypy/tool/build/client.py (original)
+++ pypy/dist/pypy/tool/build/client.py Mon Jan 8 10:59:30 2007
@@ -149,6 +149,9 @@
if config.server in ['localhost', '127.0.0.1']:
gw = PopenGateway()
else:
+ print "It may be that you have to enter your ssh-password for %s" % (
+ config.server, )
+ print "if you don't have your keys configured properly"
gw = SshGateway(config.server)
channel = init(gw,
From guido at codespeak.net Mon Jan 8 11:12:26 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 11:12:26 +0100 (CET)
Subject: [pypy-svn] r36229 - in pypy/dist/pypy/tool/build: . bin
Message-ID: <20070108101226.1445210076@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 11:12:25 2007
New Revision: 36229
Modified:
pypy/dist/pypy/tool/build/bin/client
pypy/dist/pypy/tool/build/client.py
Log:
(cfbolz, guido): Logging to the buildtemp now to allow multiple builds to run
at the same time.
Modified: pypy/dist/pypy/tool/build/bin/client
==============================================================================
--- pypy/dist/pypy/tool/build/bin/client (original)
+++ pypy/dist/pypy/tool/build/bin/client Mon Jan 8 11:12:25 2007
@@ -5,7 +5,7 @@
from py.execnet import PopenGateway
from pypy.tool.build import outputbuffer
-def compile(wc, compileinfo):
+def compile(wc, compileinfo, buildpath):
code = """\
import sys
import os
@@ -21,7 +21,7 @@
compileinfo = %r
# log locally too
- log = open('/tmp/buildclient.log', 'a')
+ log = open('%s/compile.log', 'a')
outbuffer = OutputBuffer(log)
sys.stdout = outbuffer
sys.stderr = outbuffer
@@ -63,7 +63,8 @@
"""
gw = PopenGateway()
interpolated = py.code.Source(outputbuffer,
- code % (str(wc), compileinfo))
+ code % (str(wc), compileinfo,
+ str(buildpath)))
channel = gw.remote_exec(interpolated)
try:
upath = channel.receive()
Modified: pypy/dist/pypy/tool/build/client.py
==============================================================================
--- pypy/dist/pypy/tool/build/client.py (original)
+++ pypy/dist/pypy/tool/build/client.py Mon Jan 8 11:12:25 2007
@@ -207,7 +207,8 @@
try:
print 'starting compilation'
- upath, log = compilefunc(svnwc, request.compileinfo)
+ upath, log = compilefunc(svnwc, request.compileinfo,
+ temp)
except (SystemExit, KeyboardInterrupt):
print 'quitting...'
break
From mwh at codespeak.net Mon Jan 8 11:14:10 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Mon, 8 Jan 2007 11:14:10 +0100 (CET)
Subject: [pypy-svn] r36230 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070108101410.A5CD21007A@code0.codespeak.net>
Author: mwh
Date: Mon Jan 8 11:14:08 2007
New Revision: 36230
Modified:
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
add a stub method that allows at least one test_genc_ts test to pass
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Mon Jan 8 11:14:08 2007
@@ -760,6 +760,9 @@
def sigToken(FUNCTYPE):
return len(FUNCTYPE.ARGS) # for now
+ def check_no_open_mc(self):
+ pass
+
# ----------------------------------------------------------------
# ppc-specific interface:
From cfbolz at codespeak.net Mon Jan 8 11:20:46 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 11:20:46 +0100 (CET)
Subject: [pypy-svn] r36231 - in pypy/dist/pypy: bin tool/build/bin
Message-ID: <20070108102046.6C6751007A@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 11:20:45 2007
New Revision: 36231
Added:
pypy/dist/pypy/bin/buildclient.py
- copied unchanged from r36230, pypy/dist/pypy/tool/build/bin/client
pypy/dist/pypy/bin/startcompile.py
- copied unchanged from r36230, pypy/dist/pypy/tool/build/bin/startcompile
Removed:
pypy/dist/pypy/tool/build/bin/client
pypy/dist/pypy/tool/build/bin/startcompile
Log:
(guido, cfbolz): move the build client and startcompile scripts to pypy/bin for
easier accessibility
From arigo at codespeak.net Mon Jan 8 11:33:14 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 11:33:14 +0100 (CET)
Subject: [pypy-svn] r36236 - pypy/branch/jit-codegen-refactor
Message-ID: <20070108103314.0CB4E10078@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 11:33:12 2007
New Revision: 36236
Added:
pypy/branch/jit-codegen-refactor/
- copied from r36235, pypy/dist/
Log:
(mwh, arigo)
A (hopefully short-lived) branch to refactor a bit the codegen interface
of the JIT, using enter_next_block() less often. This should make
register allocation easier.
From pedronis at codespeak.net Mon Jan 8 11:59:23 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Mon, 8 Jan 2007 11:59:23 +0100 (CET)
Subject: [pypy-svn] r36243 - pypy/dist/pypy/jit/timeshifter/test
Message-ID: <20070108105923.C1F0B10083@code0.codespeak.net>
Author: pedronis
Date: Mon Jan 8 11:59:20 2007
New Revision: 36243
Added:
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (contents, props changed)
Log:
(arre, pedronis)
first try at a test about virtualizable/deconstructible structures (to be used later for things like interpreter frames)
Added: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Mon Jan 8 11:59:20 2007
@@ -0,0 +1,51 @@
+from pypy.jit.timeshifter.test.test_portal import PortalTest, P_NOVIRTUAL
+from pypy.rpython.lltypesystem import lltype
+
+import py
+
+class TestVirtualizable(PortalTest):
+
+ def test_simple_explicit(self):
+ py.test.skip("WIP")
+ XY = lltype.GcForwardReference()
+ GETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY)], lltype.Signed))
+ SETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY), lltype.Signed],
+ lltype.Void))
+ XY_ACCESS = lltype.Struct('xy',
+ ('get_x', GETTER),
+ ('set_x', SETTER),
+ ('get_y', GETTER),
+ ('set_y', SETTER),
+ hints = {'immutable': True},
+ )
+
+ XY.become(lltype.GcStruct('xy',
+ ('access', lltype.Ptr(XY_ACCESS)),
+ ('x', lltype.Signed),
+ ('y', lltype.Signed),
+ hints = {'virtualizable': True}
+ ))
+
+ def f(xy):
+ xy_access = xy.access
+ if xy_access:
+ x = xy_access.get_x(xy)
+ else:
+ x = xy.x
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ return x+y
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ return f(xy)
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=0) # maybe?
From guido at codespeak.net Mon Jan 8 12:15:47 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 12:15:47 +0100 (CET)
Subject: [pypy-svn] r36244 - in pypy/dist/pypy/tool/build: . test
Message-ID: <20070108111547.64E5310070@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 12:15:46 2007
New Revision: 36244
Modified:
pypy/dist/pypy/tool/build/client.py
pypy/dist/pypy/tool/build/test/test_client.py
Log:
(cfbolz, guido): not adding .o files to zip
Modified: pypy/dist/pypy/tool/build/client.py
==============================================================================
--- pypy/dist/pypy/tool/build/client.py (original)
+++ pypy/dist/pypy/tool/build/client.py Mon Jan 8 12:15:46 2007
@@ -125,6 +125,8 @@
def zip_dir(res_dir, tofile):
zip = ZipFile(tofile, 'w')
for fpath in res_dir.visit():
+ if fpath.ext in ['.o']:
+ continue
try:
zip.writestr(fpath.relto(res_dir), fpath.read())
except (py.error.ENOENT, py.error.EISDIR), exc:
Modified: pypy/dist/pypy/tool/build/test/test_client.py
==============================================================================
--- pypy/dist/pypy/tool/build/test/test_client.py (original)
+++ pypy/dist/pypy/tool/build/test/test_client.py Mon Jan 8 12:15:46 2007
@@ -86,6 +86,7 @@
tempdir = py.test.ensuretemp('zip_dir')
tempdir.mkdir('foo')
tempdir.join('foo/bar.txt').write('bar')
+ tempdir.join('foo/bar.o').write('this should not be in the zip (.o file)')
zip = StringIO()
client.zip_dir(tempdir, zip)
@@ -95,6 +96,8 @@
data = zf.read('foo/bar.txt')
assert data == 'bar'
+ py.test.raises(KeyError, 'zf.read("foo/bar.o")')
+
def test_tempdir():
parent = py.test.ensuretemp('tempdir')
for i in range(10):
From guido at codespeak.net Mon Jan 8 12:24:09 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 12:24:09 +0100 (CET)
Subject: [pypy-svn] r36246 - pypy/dist/pypy/tool/build/bin
Message-ID: <20070108112409.4937910069@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 12:24:07 2007
New Revision: 36246
Added:
pypy/dist/pypy/tool/build/bin/gentoo_init.d (contents, props changed)
Log:
(cfbolz, guido): init.d script for the meta server (Gentoo specific)
Added: pypy/dist/pypy/tool/build/bin/gentoo_init.d
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/tool/build/bin/gentoo_init.d Mon Jan 8 12:24:07 2007
@@ -0,0 +1,19 @@
+#!/sbin/runscript
+
+CMD=/opt/pypy-dist/pypy/tool/build/bin/server
+
+depend() {
+ use net
+}
+
+start() {
+ ebegin "Starting PyPy meta server"
+ start-stop-daemon --start --quiet --exec $CMD
+ eend $?
+}
+
+stop() {
+ ebegin "Stopping PyPy meta server"
+ start-stop-daemon --stop --quiet --exec $CMD
+ eend $?
+}
From cfbolz at codespeak.net Mon Jan 8 12:35:34 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 12:35:34 +0100 (CET)
Subject: [pypy-svn] r36247 - pypy/dist/pypy/tool/build/bin
Message-ID: <20070108113534.75B291007A@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 12:35:32 2007
New Revision: 36247
Added:
pypy/dist/pypy/tool/build/bin/__init__.py
Log:
(guido, cfbolz) add an init file
Added: pypy/dist/pypy/tool/build/bin/__init__.py
==============================================================================
From cfbolz at codespeak.net Mon Jan 8 12:37:52 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 12:37:52 +0100 (CET)
Subject: [pypy-svn] r36248 - pypy/dist/pypy/bin
Message-ID: <20070108113752.74EB71007A@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 12:37:51 2007
New Revision: 36248
Modified:
pypy/dist/pypy/bin/buildclient.py
Log:
(guido, cfbolz) correct import
Modified: pypy/dist/pypy/bin/buildclient.py
==============================================================================
--- pypy/dist/pypy/bin/buildclient.py (original)
+++ pypy/dist/pypy/bin/buildclient.py Mon Jan 8 12:37:51 2007
@@ -79,7 +79,7 @@
if __name__ == '__main__':
# main bit
- import path
+ from pypy.tool.build.bin import path
from pypy.tool.build import config
from pypy.tool.build.client import main
From guido at codespeak.net Mon Jan 8 12:39:34 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 12:39:34 +0100 (CET)
Subject: [pypy-svn] r36250 - pypy/dist/pypy/bin
Message-ID: <20070108113934.D30161007D@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 12:39:31 2007
New Revision: 36250
Modified:
pypy/dist/pypy/bin/jscompile.py
pypy/dist/pypy/bin/startcompile.py
Log:
(cfbolz, guido) fixed path import
Modified: pypy/dist/pypy/bin/jscompile.py
==============================================================================
--- pypy/dist/pypy/bin/jscompile.py (original)
+++ pypy/dist/pypy/bin/jscompile.py Mon Jan 8 12:39:31 2007
@@ -15,7 +15,7 @@
def process_options(argv):
jsconfig = Config(js_optiondescr)
- parser, to_optparse(jsconfig)
+ parser = to_optparse(jsconfig)
parser.disable_interspersed_args()
options, args = parser.parse_args(argv)
return args, jsconfig
@@ -25,4 +25,5 @@
curdir = os.getcwd()
if curdir not in sys.path:
sys.path.insert(0, curdir)
- rpython2javascript_main(args, jsconfig)
+ print args
+ rpython2javascript_main(args[1:], jsconfig)
Modified: pypy/dist/pypy/bin/startcompile.py
==============================================================================
--- pypy/dist/pypy/bin/startcompile.py (original)
+++ pypy/dist/pypy/bin/startcompile.py Mon Jan 8 12:39:31 2007
@@ -1,7 +1,7 @@
#!/usr/bin/python
import autopath
-import path
+from pypy.tool.build.bin import path
import sys
import random
from pypy.tool.build import config
From guido at codespeak.net Mon Jan 8 12:40:17 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 12:40:17 +0100 (CET)
Subject: [pypy-svn] r36251 - in pypy/dist/pypy/translator/js/modules: . test
Message-ID: <20070108114017.F38691007D@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 12:40:15 2007
New Revision: 36251
Modified:
pypy/dist/pypy/translator/js/modules/dom.py
pypy/dist/pypy/translator/js/modules/test/test_dom.py
Log:
Removed stale import, small docstring addition.
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Mon Jan 8 12:40:15 2007
@@ -3,6 +3,9 @@
this provides a mock browser API, both the standard DOM level 2 stuff as
the browser-specific additions
+
+ in addition this provides the necessary descriptions that allow rpython
+ code that calls the browser DOM API to be translated
note that the API is not and will not be complete: more exotic features
will most probably not behave as expected, or are not implemented at all
Modified: pypy/dist/pypy/translator/js/modules/test/test_dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/test/test_dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/test/test_dom.py Mon Jan 8 12:40:15 2007
@@ -1,7 +1,6 @@
import py
from pypy.translator.js.modules import dom
from pypy.translator.js.main import rpython2javascript
-from pypy.rpython.ootypesystem.bltregistry import BasicExternal, described
from xml.dom.minidom import parseString
import sys
From guido at codespeak.net Mon Jan 8 12:42:52 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 12:42:52 +0100 (CET)
Subject: [pypy-svn] r36252 - pypy/dist/pypy/tool/build/bin
Message-ID: <20070108114252.6FEC810080@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 12:42:51 2007
New Revision: 36252
Modified:
pypy/dist/pypy/tool/build/bin/gentoo_init.d
Log:
(cfbolz, guido) backgrounding process, taking care of logging and pid file.
Modified: pypy/dist/pypy/tool/build/bin/gentoo_init.d
==============================================================================
--- pypy/dist/pypy/tool/build/bin/gentoo_init.d (original)
+++ pypy/dist/pypy/tool/build/bin/gentoo_init.d Mon Jan 8 12:42:51 2007
@@ -1,6 +1,8 @@
#!/sbin/runscript
CMD=/opt/pypy-dist/pypy/tool/build/bin/server
+PIDFILE=/var/run/build_metaserver.pid
+LOGFILE=/var/log/build_metaserver.log
depend() {
use net
@@ -8,7 +10,8 @@
start() {
ebegin "Starting PyPy meta server"
- start-stop-daemon --start --quiet --exec $CMD
+ start-stop-daemon --start --quiet --exec $CMD \
+ --make-pidfile --pidfile $PIDFILE --background >> $LOGFILE
eend $?
}
From mwh at codespeak.net Mon Jan 8 12:45:05 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Mon, 8 Jan 2007 12:45:05 +0100 (CET)
Subject: [pypy-svn] r36254 - pypy/dist/pypy/doc
Message-ID: <20070108114505.92C3F10079@code0.codespeak.net>
Author: mwh
Date: Mon Jan 8 12:45:01 2007
New Revision: 36254
Modified:
pypy/dist/pypy/doc/glossary.txt
Log:
add some JIT terminology to the glossary
Modified: pypy/dist/pypy/doc/glossary.txt
==============================================================================
--- pypy/dist/pypy/doc/glossary.txt (original)
+++ pypy/dist/pypy/doc/glossary.txt Mon Jan 8 12:45:01 2007
@@ -17,15 +17,21 @@
.. _backend:
-**backend**
+**backend**
Code generator that converts an `RPython
`__ program to a `target
language`_ using the PyPy toolchain_. A backend uses either the
lltypesystem_ or the ootypesystem_.
+.. _`compile-time`:
+
+**compile-time**
+ In the context of the JIT_, compile time is when the JIT is
+ generating machine code "just in time".
+
.. _CPython:
-**CPython**
+**CPython**
The "default" implementation of Python, written in C and
distributed by the PSF_ on http://www.python.org.
@@ -53,8 +59,9 @@
.. _`jit`:
**jit**
- `just in time compiler`_
-
+ `just in time compiler`_. Our jit now has `some draft documentation
+ `__.
+
.. _`l3interpreter`:
**l3interpreter**
@@ -88,7 +95,7 @@
a module that accesses PyPy's `interpreter level`_. The name comes
from the fact that the module's implementation can be a mixture of
`application level`_ and `interpreter level`_ code.
-
+
.. _`object space`:
**object space**
@@ -117,6 +124,13 @@
.. _`rpython`:
+.. _`promotion`:
+
+**promotion**
+ JIT_ terminology. *promotion* is a way of "using" a `run-time`_
+ value at `compile-time`_, essentially by deferring compilation
+ until the run-time value is known. See if `the jit docs`_ help.
+
**rpython**
`Restricted Python`_, a limited subset of the Python_ language.
The limitations make `type inference`_ possible.
@@ -130,6 +144,12 @@
graph into one that fits the model of the target platform/backend_
using either the lltypesystem_ or the ootypesystem_.
+.. _`run-time`:
+
+**run-time**
+ In the context of the JIT_, run time is when the code the JIT has
+ generated is executing.
+
.. _`specialization`:
**specialization**
@@ -153,6 +173,11 @@
.. _toolchain:
+**timeshifting**
+ JIT_ terminology. *timeshifting* is to do with moving from the
+ world where there are only `run-time`_ operations to a world where
+ there are both `run-time`_ and `compile-time`_ operations.
+
**toolchain**
The `annotator pass`_, `The RPython Typer`_, and various
`backends`_.
@@ -162,6 +187,12 @@
**transformation**
Code that modifies flowgraphs to weave in `translation-aspects`_
+.. _`translation-time`:
+
+**translation-time**
+ In the context of the JIT_, translation time is when the PyPy
+ source is being analysed and the JIT itself is being created.
+
.. _`translator`:
**translator**
@@ -184,6 +215,7 @@
.. _applevel: coding-guide.html#application-level
.. _`target language`: getting-started.html#trying-out-the-translator
.. _`just in time compiler`: http://en.wikipedia.org/wiki/Just-in-time_compilation
+.. _`the jit docs`: jit.html
.. _`type inference article on Wikipedia`: http://en.wikipedia.org/wiki/Type_inference
.. _`annotator pass`: translation.html#the-annotation-pass
.. _`The RPython Typer`: translation.html#the-rpython-typer
From arigo at codespeak.net Mon Jan 8 13:04:25 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 13:04:25 +0100 (CET)
Subject: [pypy-svn] r36257 - in
pypy/branch/jit-codegen-refactor/pypy/jit/codegen: . llgraph
llgraph/test
Message-ID: <20070108120425.A45201007D@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 13:04:19 2007
New Revision: 36257
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
Log:
(mwh, arigo)
New rgenop interface, implemented for the llgraph backend.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py Mon Jan 8 13:04:19 2007
@@ -350,6 +350,31 @@
graph = _getgraph(gv_func)
_closelink(link, [returnvar], graph.prereturnblock)
+def closelinktofreshblock(link, inputargs=None):
+ link = from_opaque_object(link)
+ vars = link.prevblock.getvariables()
+ if inputargs is not None:
+ existing_vars = dict.fromkeys(vars)
+ vars = _inputvars(inputargs)
+ for v in vars:
+ assert v in existing_vars
+ nextblock = flowmodel.Block(list(vars))
+ link.args = vars
+ link.target = nextblock
+ return to_opaque_object(nextblock)
+
+def closelinktofreshblockwithsameargsasotherlink(link, otherlink):
+ link = from_opaque_object(link)
+ otherlink = from_opaque_object(otherlink)
+ existing_vars = dict.fromkeys(link.prevblock.getvariables())
+ vars = list(otherlink.args)
+ for v in vars:
+ assert v in existing_vars
+ nextblock = flowmodel.Block(list(vars))
+ link.args = vars
+ link.target = nextblock
+ return to_opaque_object(nextblock)
+
def casting_link(source, sourcevars, target):
assert len(sourcevars) == len(target.inputargs)
linkargs = []
@@ -372,7 +397,27 @@
from pypy.rpython.typesystem import LowLevelTypeSystem
self.type_system = LowLevelTypeSystem.instance
+def fixduplicatevars(graph):
+ incomingvars = {} # {block: {var_from_link_args: True}}
+ for link in graph.iterlinks():
+ vars = incomingvars.setdefault(link.target, {})
+ for v in link.args:
+ if isinstance(v, flowmodel.Variable):
+ vars[v] = True
+ for block, vars in incomingvars.items():
+ for v in block.inputargs:
+ if v in vars:
+ # this block needs renaming of all its input variables
+ mapping = {}
+ for a in block.inputargs:
+ mapping[a] = a1 = flowmodel.Variable(a)
+ a1.concretetype = a.concretetype
+ block.renamevariables(mapping)
+ break
+
def _buildgraph(graph):
+ # rgenop makes graphs that use the same variable in several blocks,
+ fixduplicatevars(graph) # fix this now
flowmodel.checkgraph(graph)
eliminate_empty_blocks(graph)
join_blocks(graph)
@@ -486,6 +531,8 @@
setannotation(add_default, s_Link)
setannotation(closelink, None)
setannotation(closereturnlink, None)
+setannotation(closelinktofreshblock, s_Block)
+setannotation(closelinktofreshblockwithsameargsasotherlink, s_Block)
setannotation(isptrtype, annmodel.SomeBool())
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 13:04:19 2007
@@ -55,22 +55,22 @@
def add_case(self, gv_case):
self.cases_gv.append(gv_case) # not used so far, but keeps ptrs alive
l_case = llimpl.add_case(self.b, gv_case.v)
- builder = LLBuilder(self.gv_f)
- builder.lnk = l_case
- return builder
+ b = llimpl.closelinktofreshblockwithsameargsasotherlink(l_case,
+ self.l_default)
+ return LLBuilder(self.gv_f, b)
- def add_default(self):
+ def _add_default(self, args_gv):
l_default = llimpl.add_default(self.b)
- builder = LLBuilder(self.gv_f)
- builder.lnk = l_default
- return builder
+ self.l_default = l_default
+ b = llimpl.closelinktofreshblock(l_default, args_gv)
+ return LLBuilder(self.gv_f, b)
class LLBuilder(GenBuilder):
- lnk = llimpl.nulllink
- def __init__(self, g):
+ def __init__(self, g, block):
self.rgenop = rgenop
self.gv_f = g
+ self.b = block
def end(self):
llimpl.end(self.gv_f)
@@ -156,8 +156,7 @@
return [LLVar(llimpl.geninputarg(newb, kind.v)) for kind in kinds]
def enter_next_block(self, kinds, args_gv):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
newb_args_gv = self._newblock(kinds)
llimpl.closelink(lnk, args_gv, self.b)
for i in range(len(args_gv)):
@@ -165,38 +164,35 @@
return LLLabel(self.b, self.gv_f)
def finish_and_goto(self, args_gv, target):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
+ self.b = llimpl.nullblock
llimpl.closelink(lnk, args_gv, target.b)
def finish_and_return(self, sigtoken, gv_returnvar):
gv_returnvar = gv_returnvar or gv_dummy_placeholder
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
+ self.b = llimpl.nullblock
llimpl.closereturnlink(lnk, gv_returnvar.v, self.gv_f)
- def jump_if_true(self, gv_cond):
+ def jump_if_true(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.nullblock
- later_builder = LLBuilder(self.gv_f)
- later_builder.lnk = l_true
- self.lnk = l_false
+ self.b = llimpl.closelinktofreshblock(l_false, None)
+ b2 = llimpl.closelinktofreshblock(l_true, args_for_jump_gv)
+ later_builder = LLBuilder(self.gv_f, b2)
return later_builder
- def jump_if_false(self, gv_cond):
+ def jump_if_false(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.nullblock
- later_builder = LLBuilder(self.gv_f)
- later_builder.lnk = l_false
- self.lnk = l_true
+ self.b = llimpl.closelinktofreshblock(l_true, None)
+ b2 = llimpl.closelinktofreshblock(l_false, args_for_jump_gv)
+ later_builder = LLBuilder(self.gv_f, b2)
return later_builder
- def flexswitch(self, gv_switchvar):
+ def flexswitch(self, gv_switchvar, args_gv):
llimpl.closeblockswitch(self.b, gv_switchvar.v)
flexswitch = LLFlexSwitch(self.b, self.gv_f)
self.b = llimpl.nullblock
- self.lnk = llimpl.nulllink
- return flexswitch
+ return (flexswitch, flexswitch._add_default(args_gv))
def show_incremental_progress(self):
llimpl.show_incremental_progress(self.gv_f)
@@ -208,8 +204,7 @@
def newgraph(self, (ARGS_gv, gv_RESULT, gv_FUNCTYPE), name):
gv_func = llimpl.newgraph(gv_FUNCTYPE.v, name)
- builder = LLBuilder(gv_func)
- builder.b = llimpl.getstartblock(gv_func)
+ builder = LLBuilder(gv_func, llimpl.getstartblock(gv_func))
inputargs_gv = [LLVar(llimpl.getinputarg(builder.b, i))
for i in range(len(ARGS_gv))]
return builder, LLConst(gv_func), inputargs_gv
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py Mon Jan 8 13:04:19 2007
@@ -67,7 +67,7 @@
const0 = rgenop.genconst(0)
gv1 = builder.genop2('int_lt', gv0, const0)
- false_builder = builder.jump_if_false(gv1)
+ false_builder = builder.jump_if_false(gv1, [gv0])
builder.finish_and_return(f1_token, const0)
false_builder.finish_and_return(f1_token, gv0)
builder.end()
@@ -110,7 +110,7 @@
gv_result1 = builder.genop2('int_mul', gv_result0, gv_i0)
gv_i1 = builder.genop2('int_add', gv_i0, const1)
gv2 = builder.genop2('int_le', gv_i1, gv1)
- loop_builder = builder.jump_if_true(gv2)
+ loop_builder = builder.jump_if_true(gv2, [gv_result1, gv_i1, gv1])
builder.finish_and_return(f1_token, gv_result1)
loop_builder.finish_and_goto([gv_result1, gv_i1, gv1], loopblock)
@@ -167,31 +167,21 @@
"""
builder, gv_switch, (gv0, gv1) = rgenop.newgraph(f2_token, "switch")
- flexswitch = builder.flexswitch(gv0)
+ flexswitch, default_builder = builder.flexswitch(gv0, [gv1])
const21 = rgenop.genconst(21)
# case == 0
const0 = rgenop.genconst(0)
case_builder = flexswitch.add_case(const0)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case0] = case_args_gv
- gv_res_case0 = case_builder.genop2('int_mul', const21, gv1_case0)
+ gv_res_case0 = case_builder.genop2('int_mul', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case0)
# case == 1
const1 = rgenop.genconst(1)
case_builder = flexswitch.add_case(const1)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case1] = case_args_gv
- gv_res_case1 = case_builder.genop2('int_add', const21, gv1_case1)
+ gv_res_case1 = case_builder.genop2('int_add', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case1)
# default
- default_builder = flexswitch.add_default()
- default_args_gv = [gv1]
- default_builder.enter_next_block([signed_tok], default_args_gv)
- [gv1_default] = default_args_gv
- default_builder.finish_and_return(f2_token, gv1_default)
+ default_builder.finish_and_return(f2_token, gv1)
builder.end()
switch_ptr = gv_switch.revealconst(lltype.Ptr(F2))
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py Mon Jan 8 13:04:19 2007
@@ -86,22 +86,27 @@
zip(kinds, args_gv) gives the kindtoken and GenVarOrConst for
each inputarg of the block.
- The Obscure Bit: args_gv must be mutated in place to replace
- GenConsts with GenVars and optionally GenVars can be replaced
- with new GenVars, for example if the same value might live in
- different locations (registers, places on the stack) in
- different basic blocks.
+ The Obscure Bit: args_gv must be mutated in place until it is a
+ list of unique GenVars. So GenConsts must be replaced with
+ GenVars, and duplicate GenVars must be made unique. Optionally,
+ *all* GenVars can be replaced with new GenVars, for example if
+ the same value might live in different locations (registers,
+ places on the stack) in different basic blocks.
Returns an instance of GenLabel that can later be jumped to.
'''
- def jump_if_false(self, gv_condition):
+ def jump_if_false(self, gv_condition, args_for_jump_gv):
'''Make a fresh builder, insert in the current block a
check of gv_condition and a conditional jump to the new block
that is taken if gv_condition is false and return the new
- builder.'''
+ builder.
- def jump_if_true(self, gv_condition):
+ The current builder stays open, and it must be closed before
+ the fresh builder is used at all, to make the backend\'s life
+ easier.'''
+
+ def jump_if_true(self, gv_condition, args_for_jump_gv):
'''See above, with the obvious difference :)'''
def finish_and_return(self, sigtoken, gv_returnvar):
@@ -120,14 +125,20 @@
This "closes" the current builder.
'''
- def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch, args_gv):
'''The Fun Stuff.
Generates a switch on the value of gv_exitswitch that can have
cases added to it later, i.e. even after it\'s been executed a
few times.
- Returns an instance of CodeGenSwitch, see below.
+ args_gv is the list of live variables. It\'s the list of
+ variables that can be used in each switch case.
+
+ Returns a tuple:
+ - an instance of CodeGenSwitch (see below)
+ - a new builder for the default case, that will be jumped to
+ when the switched-on GenVar does not take the value of any case.
This "closes" the current builder.
'''
@@ -258,8 +269,3 @@
def add_case(self, gv_case):
'''Make a new builder that will be jumped to when the
switched-on GenVar takes the value of the GenConst gv_case.'''
-
- def add_default(self):
- '''Make a new builder that will be jumped to when the
- switched-on GenVar does not take the value of any case.'''
-
From arigo at codespeak.net Mon Jan 8 13:15:18 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 13:15:18 +0100 (CET)
Subject: [pypy-svn] r36258 -
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph
Message-ID: <20070108121518.803091007F@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 13:15:15 2007
New Revision: 36258
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
Log:
(mwh, arigo)
A hack to make sure that the builders returned by jump_if_xxx() are not
used before the original builder is closed.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 13:15:15 2007
@@ -71,6 +71,7 @@
self.rgenop = rgenop
self.gv_f = g
self.b = block
+ self.jumped_to_builders = []
def end(self):
llimpl.end(self.gv_f)
@@ -165,35 +166,45 @@
def finish_and_goto(self, args_gv, target):
lnk = llimpl.closeblock1(self.b)
- self.b = llimpl.nullblock
llimpl.closelink(lnk, args_gv, target.b)
+ self._close()
def finish_and_return(self, sigtoken, gv_returnvar):
gv_returnvar = gv_returnvar or gv_dummy_placeholder
lnk = llimpl.closeblock1(self.b)
- self.b = llimpl.nullblock
llimpl.closereturnlink(lnk, gv_returnvar.v, self.gv_f)
+ self._close()
def jump_if_true(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
self.b = llimpl.closelinktofreshblock(l_false, None)
b2 = llimpl.closelinktofreshblock(l_true, args_for_jump_gv)
- later_builder = LLBuilder(self.gv_f, b2)
+ later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
+ later_builder.later_block = b2
+ self.jumped_to_builders.append(later_builder)
return later_builder
def jump_if_false(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
self.b = llimpl.closelinktofreshblock(l_true, None)
b2 = llimpl.closelinktofreshblock(l_false, args_for_jump_gv)
- later_builder = LLBuilder(self.gv_f, b2)
+ later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
+ later_builder.later_block = b2
+ self.jumped_to_builders.append(later_builder)
return later_builder
def flexswitch(self, gv_switchvar, args_gv):
llimpl.closeblockswitch(self.b, gv_switchvar.v)
flexswitch = LLFlexSwitch(self.b, self.gv_f)
- self.b = llimpl.nullblock
+ self._close()
return (flexswitch, flexswitch._add_default(args_gv))
+ def _close(self):
+ self.b = llimpl.nullblock
+ for builder in self.jumped_to_builders:
+ builder.b = builder.later_block
+ builder.later_block = llimpl.nullblock
+
def show_incremental_progress(self):
llimpl.show_incremental_progress(self.gv_f)
From afayolle at codespeak.net Mon Jan 8 13:35:14 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Mon, 8 Jan 2007 13:35:14 +0100 (CET)
Subject: [pypy-svn] r36260 - in pypy/dist/pypy: lang/js/test translator/cl
translator/cli translator/js/test translator/jvm
translator/llvm translator/squeak/test
Message-ID: <20070108123514.8E18910068@code0.codespeak.net>
Author: afayolle
Date: Mon Jan 8 13:35:13 2007
New Revision: 36260
Modified:
pypy/dist/pypy/lang/js/test/test_interp.py
pypy/dist/pypy/translator/cl/buildcl.py
pypy/dist/pypy/translator/cli/sdk.py
pypy/dist/pypy/translator/js/test/runtest.py
pypy/dist/pypy/translator/jvm/genjvm.py
pypy/dist/pypy/translator/llvm/buildllvm.py
pypy/dist/pypy/translator/squeak/test/runtest.py
Log:
updated sysfind usage to new smeantics.
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Mon Jan 8 13:35:13 2007
@@ -11,9 +11,7 @@
def js_is_on_path():
- try:
- py.path.local.sysfind("js")
- except py.error.ENOENT:
+ if py.path.local.sysfind("js") is None:
py.test.skip("js binary not found")
js_is_on_path()
Modified: pypy/dist/pypy/translator/cl/buildcl.py
==============================================================================
--- pypy/dist/pypy/translator/cl/buildcl.py (original)
+++ pypy/dist/pypy/translator/cl/buildcl.py Mon Jan 8 13:35:13 2007
@@ -11,12 +11,9 @@
global_cl = None
def is_on_path(name):
- try:
- py.path.local.sysfind(name)
- except py.error.ENOENT:
+ if py.path.local.sysfind(name) is None:
return False
- else:
- return True
+ return True
def cl_detect():
cl = os.getenv("PYPY_CL")
Modified: pypy/dist/pypy/translator/cli/sdk.py
==============================================================================
--- pypy/dist/pypy/translator/cli/sdk.py (original)
+++ pypy/dist/pypy/translator/cli/sdk.py Mon Jan 8 13:35:13 2007
@@ -3,11 +3,10 @@
class AbstractSDK(object):
def _check_helper(cls, helper):
- try:
- py.path.local.sysfind(helper)
- return helper
- except py.error.ENOENT:
+ if py.path.local.sysfind(helper) is None:
py.test.skip("%s is not on your path." % helper)
+ else:
+ return helper
_check_helper = classmethod(_check_helper)
def runtime(cls):
Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py (original)
+++ pypy/dist/pypy/translator/js/test/runtest.py Mon Jan 8 13:35:13 2007
@@ -24,9 +24,7 @@
port = 8080
def _CLI_is_on_path():
- try:
- py.path.local.sysfind('js') #we recommend Spidermonkey
- except py.error.ENOENT:
+ if py.path.local.sysfind('js') is None: #we recommend Spidermonkey
return False
return True
Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py (original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py Mon Jan 8 13:35:13 2007
@@ -160,9 +160,7 @@
def detect_missing_support_programs():
def check(exechelper):
- try:
- py.path.local.sysfind(exechelper)
- except py.error.ENOENT:
+ if py.path.local.sysfind(exechelper) is None:
py.test.skip("%s is not on your path" % exechelper)
check(getoption('jasmin'))
check(getoption('javac'))
Modified: pypy/dist/pypy/translator/llvm/buildllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/buildllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/buildllvm.py Mon Jan 8 13:35:13 2007
@@ -10,10 +10,8 @@
import distutils.sysconfig
def llvm_is_on_path():
- try:
- py.path.local.sysfind("llvm-as")
- py.path.local.sysfind("llvm-gcc")
- except py.error.ENOENT:
+ if py.path.local.sysfind("llvm-as") is None or \
+ py.path.local.sysfind("llvm-gcc") is None:
return False
return True
Modified: pypy/dist/pypy/translator/squeak/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/squeak/test/runtest.py (original)
+++ pypy/dist/pypy/translator/squeak/test/runtest.py Mon Jan 8 13:35:13 2007
@@ -14,9 +14,7 @@
import posix
except ImportError:
py.test.skip("Squeak tests only work on Unix right now.")
- try:
- py.path.local.sysfind("squeak")
- except py.error.ENOENT:
+ if py.path.local.sysfind("squeak") is None:
py.test.skip("Squeak is not on your path.")
if os.getenv("SQUEAK_IMAGE") is None:
py.test.skip("Squeak tests expect the SQUEAK_IMAGE environment "
From arigo at codespeak.net Mon Jan 8 13:38:26 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 13:38:26 +0100 (CET)
Subject: [pypy-svn] r36261 -
pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter
Message-ID: <20070108123826.40E6410068@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 13:38:21 2007
New Revision: 36261
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py
pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py
Log:
(mwh, arigo)
Start porting the timeshifter to use the new rgenop interface.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py Mon Jan 8 13:38:21 2007
@@ -330,7 +330,8 @@
node = resuming.path.pop()
assert isinstance(node, PromotionPathSplit)
return node.answer
- later_builder = jitstate.curbuilder.jump_if_false(exitgvar)
+ locals_gv = jitstate.get_locals_gv()
+ later_builder = jitstate.curbuilder.jump_if_false(exitgvar, locals_gv)
jitstate2 = jitstate.split(later_builder, resumepoint, list(greens_gv))
if resuming is None:
node = jitstate.promotion_path
@@ -864,6 +865,15 @@
self.exc_type_box = self.exc_type_box .replace(memo)
self.exc_value_box = self.exc_value_box.replace(memo)
+ def get_locals_gv(self):
+ # get all the genvars that are "alive", i.e. stored in the JITState
+ # or the VirtualFrames
+ incoming = []
+ memo = rvalue.enter_block_memo()
+ self.enter_block(incoming, memo)
+ locals_gv = [redbox.genvar for redbox in incoming]
+ return locals_gv
+
def residual_ll_exception(self, ll_evalue):
ll_etype = ll_evalue.typeptr
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py Mon Jan 8 13:38:21 2007
@@ -290,19 +290,19 @@
resulttype = lltype.Bool)
block.exitswitch = v_flag
- true_block = Block([])
- true_link = Link([], true_block)
- true_link.exitcase = True
- true_link.llexitcase = True
- block.recloseblock(link_f, true_link)
-
- reds, greens = self.sort_by_color(link_t.args)
- self.genop(true_block, 'save_locals', reds)
- self.genop(true_block, 'enter_block', [])
- true_block.closeblock(Link(link_t.args, link_t.target))
+## true_block = Block([])
+## true_link = Link([], true_block)
+## true_link.exitcase = True
+## true_link.llexitcase = True
+## block.recloseblock(link_f, true_link)
+
+## reds, greens = self.sort_by_color(link_t.args)
+## self.genop(true_block, 'save_locals', reds)
+## self.genop(true_block, 'enter_block', [])
+## true_block.closeblock(Link(link_t.args, link_t.target))
- SSA_to_SSI({block : True, # reachable from outside
- true_block: False}, self.hannotator)
+## SSA_to_SSI({block : True, # reachable from outside
+## true_block: False}, self.hannotator)
def get_resume_point_link(self, block):
try:
From guido at codespeak.net Mon Jan 8 13:44:33 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 13:44:33 +0100 (CET)
Subject: [pypy-svn] r36262 - in pypy/dist/pypy/tool/build: . test
Message-ID: <20070108124433.6A1FB10070@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 13:44:30 2007
New Revision: 36262
Added:
pypy/dist/pypy/tool/build/buildserver.py
- copied, changed from r36257, pypy/dist/pypy/tool/build/client.py
pypy/dist/pypy/tool/build/metaserver.py
- copied, changed from r36257, pypy/dist/pypy/tool/build/server.py
pypy/dist/pypy/tool/build/test/test_buildserver.py
- copied, changed from r36257, pypy/dist/pypy/tool/build/test/test_client.py
pypy/dist/pypy/tool/build/test/test_metaserver.py
- copied, changed from r36257, pypy/dist/pypy/tool/build/test/test_server.py
Removed:
pypy/dist/pypy/tool/build/client.py
pypy/dist/pypy/tool/build/server.py
pypy/dist/pypy/tool/build/test/test_client.py
pypy/dist/pypy/tool/build/test/test_server.py
Modified:
pypy/dist/pypy/tool/build/build.py
pypy/dist/pypy/tool/build/test/fake.py
pypy/dist/pypy/tool/build/test/test_pypybuilder.py
Log:
(cfbolz, guido) renaming 'server.PPBServer' to 'metaserver.MetaServer' and
'client.PPBClient' to 'buildserver.BuildServer'.
Modified: pypy/dist/pypy/tool/build/build.py
==============================================================================
--- pypy/dist/pypy/tool/build/build.py (original)
+++ pypy/dist/pypy/tool/build/build.py Mon Jan 8 13:44:30 2007
@@ -79,6 +79,7 @@
_reg_error = py.std.re.compile(r'uring compilation:\n([^:]+): (.*)')
def _error(self):
+ import exceptions
if self.done and not self.zipfile.size():
log = self.log
match = self._reg_error.search(log)
Modified: pypy/dist/pypy/tool/build/test/fake.py
==============================================================================
--- pypy/dist/pypy/tool/build/test/fake.py (original)
+++ pypy/dist/pypy/tool/build/test/fake.py Mon Jan 8 13:44:30 2007
@@ -29,7 +29,7 @@
self.busy_on = request
return True
-class FakeServer(object):
+class FakeMetaServer(object):
def __init__(self, builddirpath):
builddirpath.ensure(dir=True)
self._channel = FakeChannel()
Modified: pypy/dist/pypy/tool/build/test/test_pypybuilder.py
==============================================================================
--- pypy/dist/pypy/tool/build/test/test_pypybuilder.py (original)
+++ pypy/dist/pypy/tool/build/test/test_pypybuilder.py Mon Jan 8 13:44:30 2007
@@ -6,9 +6,8 @@
import time
import path
-from pypy.tool.build import client, server, execnetconference
-from pypy.tool.build import config
-from pypy.tool.build import build
+from pypy.tool.build import metaserver, buildserver, execnetconference
+from pypy.tool.build import config, build
from pypy.tool.build.conftest import option
from pypy.config import config as pypyconfig
@@ -47,7 +46,7 @@
path=config.testpath, buildpath=temppath,
mailhost=None)
- mod.sc = sc = server.init(sgw, cfg)
+ mod.sc = sc = metaserver.init(sgw, cfg)
def read():
while 1:
@@ -57,18 +56,18 @@
break
py.std.thread.start_new_thread(read, ())
- # give the server some time to wake up
+ # give the metaserver some time to wake up
time.sleep(SLEEP_INTERVAL)
def teardown_module(mod):
mod.sc.close()
mod.sgw.exit()
-def create_client_channel(**conf):
+def create_buildserver_channel(**conf):
cgw = py.execnet.PopenGateway()
sysconfig = _get_sysconfig()
sysconfig.__dict__.update(conf)
- channel = client.init(cgw, sysconfig, port=config.testport,
+ channel = buildserver.init(cgw, sysconfig, port=config.testport,
testing_sleeptime=SLEEP_INTERVAL * 5)
channel.send(True)
return cgw, channel
@@ -78,9 +77,9 @@
import sys
sys.path += %r
- from pypy.tool.build import ppbserver
+ from pypy.tool.build import metaserver_instance
from pypy.tool.build import build
- channel.send(ppbserver.compile(%r))
+ channel.send(metaserver_instance.compile(%r))
channel.close()
"""
gw = py.execnet.PopenGateway()
@@ -105,15 +104,15 @@
import sys, time
sys.path += %r
- from pypy.tool.build import ppbserver
- ppbserver._cleanup_clients()
- ppbserver._test_waiting()
- ppbserver._try_queued()
+ from pypy.tool.build import metaserver_instance
+ metaserver_instance._cleanup_builders()
+ metaserver_instance._test_waiting()
+ metaserver_instance._try_queued()
# take some time to update all the lists
time.sleep(%s)
- data = [str(x) for x in ppbserver.%s]
+ data = [str(x) for x in metaserver_instance.%s]
channel.send(data)
channel.close()
""" % (config.testpath, SLEEP_INTERVAL, attr))
@@ -135,25 +134,26 @@
assert len(queued) == 0
waiting = get_info('_waiting')
assert len(waiting) == 0
- clients = get_info('_clients')
- assert len(clients) == 0
+ buildservers = get_info('_builders')
+ assert len(buildservers) == 0
# then we request a compilation for sysinfo foo=1, obviously this can not
# be fulfilled yet
ispath, data = compile(foo=1)
assert not ispath
- assert 'no suitable client' in data
+ assert 'no suitable build server' in data
queued = get_info('_queued')
assert len(queued) == 1
- # now we register a client with the same sysinfo, note that we don't tell
- # the server yet that the client actually accepts to handle the request
- gw, cchannel = create_client_channel(foo=1)
+ # now we register a buildserver with the same sysinfo, note that we don't
+ # tell the metaserver yet that the buildserver actually accepts to handle
+ # the request
+ gw, cchannel = create_buildserver_channel(foo=1)
try:
- clients = get_info('_clients')
- assert len(clients) == 1
+ buildservers = get_info('_builders')
+ assert len(buildservers) == 1
- # XXX quite a bit scary here, the client will take exactly
+ # XXX quite a bit scary here, the buildserver will take exactly
# 4 * SLEEP_INTERVAL seconds to fake the compilation... here we should
# (if all is well) still be compiling
@@ -189,6 +189,6 @@
cchannel.close()
gw.exit()
- clients = get_info('_clients')
- assert len(clients) == 0
+ buildservers = get_info('_builders')
+ assert len(buildservers) == 0
From guido at codespeak.net Mon Jan 8 13:46:58 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 13:46:58 +0100 (CET)
Subject: [pypy-svn] r36263 - pypy/dist/pypy/tool/build/bin
Message-ID: <20070108124658.392491007D@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 13:46:57 2007
New Revision: 36263
Added:
pypy/dist/pypy/tool/build/bin/metaserver
- copied, changed from r36257, pypy/dist/pypy/tool/build/bin/server
Removed:
pypy/dist/pypy/tool/build/bin/server
Modified:
pypy/dist/pypy/tool/build/bin/gentoo_init.d
Log:
(cfbolz, guido) Renaming the bin scripts.
Modified: pypy/dist/pypy/tool/build/bin/gentoo_init.d
==============================================================================
--- pypy/dist/pypy/tool/build/bin/gentoo_init.d (original)
+++ pypy/dist/pypy/tool/build/bin/gentoo_init.d Mon Jan 8 13:46:57 2007
@@ -1,6 +1,6 @@
#!/sbin/runscript
-CMD=/opt/pypy-dist/pypy/tool/build/bin/server
+CMD=/opt/pypy-dist/pypy/tool/build/bin/metaserver
PIDFILE=/var/run/build_metaserver.pid
LOGFILE=/var/log/build_metaserver.log
From cfbolz at codespeak.net Mon Jan 8 13:48:33 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 13:48:33 +0100 (CET)
Subject: [pypy-svn] r36264 - pypy/dist/pypy/bin
Message-ID: <20070108124833.5BCF71007F@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 13:48:32 2007
New Revision: 36264
Added:
pypy/dist/pypy/bin/buildserver.py
- copied, changed from r36262, pypy/dist/pypy/bin/buildclient.py
Removed:
pypy/dist/pypy/bin/buildclient.py
Modified:
pypy/dist/pypy/bin/startcompile.py
Log:
(guido, cfbolz): fix renames here too.
Modified: pypy/dist/pypy/bin/startcompile.py
==============================================================================
--- pypy/dist/pypy/bin/startcompile.py (original)
+++ pypy/dist/pypy/bin/startcompile.py Mon Jan 8 13:48:32 2007
@@ -29,9 +29,9 @@
sys.path += %r
try:
- from pypy.tool.build import ppbserver
+ from pypy.tool.build import metaserver_instance
from pypy.tool.build import build
- ret = ppbserver.compile(%r)
+ ret = metaserver_instance.compile(%r)
channel.send(ret)
channel.close()
except:
From cfbolz at codespeak.net Mon Jan 8 14:38:03 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 14:38:03 +0100 (CET)
Subject: [pypy-svn] r36265 - pypy/dist/pypy/rlib/parsing
Message-ID: <20070108133803.6C40510071@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 14:38:01 2007
New Revision: 36265
Modified:
pypy/dist/pypy/rlib/parsing/ebnfparse.py
Log:
remove debug print
Modified: pypy/dist/pypy/rlib/parsing/ebnfparse.py
==============================================================================
--- pypy/dist/pypy/rlib/parsing/ebnfparse.py (original)
+++ pypy/dist/pypy/rlib/parsing/ebnfparse.py Mon Jan 8 14:38:01 2007
@@ -47,7 +47,7 @@
def parse_ebnf(s):
visitor = ParserBuilder()
tokens = lexer.tokenize(s, True)
- print tokens
+ #print tokens
s = parser.parse(tokens)
s = s.visit(EBNFToAST())
assert len(s) == 1
From guido at codespeak.net Mon Jan 8 14:40:53 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 14:40:53 +0100 (CET)
Subject: [pypy-svn] r36266 - pypy/dist/pypy/tool/build
Message-ID: <20070108134053.2A3FA10071@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 14:40:51 2007
New Revision: 36266
Modified:
pypy/dist/pypy/tool/build/config.py
Log:
(cfbolz, guido) gc=boehm is now default
Modified: pypy/dist/pypy/tool/build/config.py
==============================================================================
--- pypy/dist/pypy/tool/build/config.py (original)
+++ pypy/dist/pypy/tool/build/config.py Mon Jan 8 14:40:51 2007
@@ -21,7 +21,8 @@
# cmdline args, defaults are taken from the optiondescription
from pypy.config.pypyoption import get_pypy_config
compile_config = get_pypy_config()
-compile_config.override({'translation.backend': 'c'})
+compile_config.override({'translation.backend': 'c',
+ 'translation.gc': 'boehm'})
# settings for the server
projectname = 'pypy'
From cfbolz at codespeak.net Mon Jan 8 14:51:38 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Mon, 8 Jan 2007 14:51:38 +0100 (CET)
Subject: [pypy-svn] r36271 - pypy/dist/pypy/tool
Message-ID: <20070108135138.4535610076@code0.codespeak.net>
Author: cfbolz
Date: Mon Jan 8 14:51:37 2007
New Revision: 36271
Modified:
pypy/dist/pypy/tool/ansi_print.py
Log:
ansi_print itself moved to the py-lib
Modified: pypy/dist/pypy/tool/ansi_print.py
==============================================================================
--- pypy/dist/pypy/tool/ansi_print.py (original)
+++ pypy/dist/pypy/tool/ansi_print.py Mon Jan 8 14:51:37 2007
@@ -4,21 +4,7 @@
import sys
-def ansi_print(text, esc, file=None, newline=True, flush=False):
- if file is None: file = sys.stderr
- text = text.rstrip()
- if esc and sys.platform != "win32" and file.isatty():
- if not isinstance(esc, tuple):
- esc = (esc,)
- text = (''.join(['\x1b[%sm' % cod for cod in esc]) +
- text +
- '\x1b[0m') # ANSI color code "reset"
- if newline:
- text += '\n'
- file.write(text)
- if flush:
- file.flush()
-
+from py.__.misc.terminal_helper import ansi_print
class AnsiLog:
From arigo at codespeak.net Mon Jan 8 15:01:55 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 15:01:55 +0100 (CET)
Subject: [pypy-svn] r36272 - in
pypy/branch/jit-codegen-refactor/pypy/jit/codegen: . llgraph
llgraph/test
Message-ID: <20070108140155.6BBCD10075@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 15:01:53 2007
New Revision: 36272
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
Log:
(mwh, arigo)
More refinements to the interface.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 15:01:53 2007
@@ -66,12 +66,12 @@
return LLBuilder(self.gv_f, b)
class LLBuilder(GenBuilder):
+ jumped_from = None
def __init__(self, g, block):
self.rgenop = rgenop
self.gv_f = g
self.b = block
- self.jumped_to_builders = []
def end(self):
llimpl.end(self.gv_f)
@@ -175,23 +175,21 @@
llimpl.closereturnlink(lnk, gv_returnvar.v, self.gv_f)
self._close()
- def jump_if_true(self, gv_cond, args_for_jump_gv):
- l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.closelinktofreshblock(l_false, None)
- b2 = llimpl.closelinktofreshblock(l_true, args_for_jump_gv)
+ def _jump(self, l_jump, l_no_jump, args_for_jump_gv):
+ self.b = llimpl.closelinktofreshblock(l_no_jump, None)
+ b2 = llimpl.closelinktofreshblock(l_jump, args_for_jump_gv)
later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
later_builder.later_block = b2
- self.jumped_to_builders.append(later_builder)
+ later_builder.jumped_from = self
return later_builder
+ def jump_if_true(self, gv_cond, args_for_jump_gv):
+ l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
+ return self._jump(l_true, l_false, args_for_jump_gv)
+
def jump_if_false(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.closelinktofreshblock(l_true, None)
- b2 = llimpl.closelinktofreshblock(l_false, args_for_jump_gv)
- later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
- later_builder.later_block = b2
- self.jumped_to_builders.append(later_builder)
- return later_builder
+ return self._jump(l_false, l_true, args_for_jump_gv)
def flexswitch(self, gv_switchvar, args_gv):
llimpl.closeblockswitch(self.b, gv_switchvar.v)
@@ -201,9 +199,20 @@
def _close(self):
self.b = llimpl.nullblock
- for builder in self.jumped_to_builders:
- builder.b = builder.later_block
- builder.later_block = llimpl.nullblock
+
+ def start_writing(self):
+ assert self.b == llimpl.nullblock
+ if self.jumped_from:
+ assert self.jumped_from.b == llimpl.nullblock
+ assert self.later_block != llimpl.nullblock
+ self.b = self.later_block
+ self.later_block = llimpl.nullblock
+
+ def pause_writing(self, args_gv):
+ lnk = llimpl.closeblock1(self.b)
+ b2 = llimpl.closelinktofreshblock(lnk, args_gv)
+ self.later_block = b2
+ self._close()
def show_incremental_progress(self):
llimpl.show_incremental_progress(self.gv_f)
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/test/test_rgenop.py Mon Jan 8 15:01:53 2007
@@ -69,6 +69,7 @@
gv1 = builder.genop2('int_lt', gv0, const0)
false_builder = builder.jump_if_false(gv1, [gv0])
builder.finish_and_return(f1_token, const0)
+ false_builder.start_writing()
false_builder.finish_and_return(f1_token, gv0)
builder.end()
if_ptr = gv_if.revealconst(lltype.Ptr(F1))
@@ -112,6 +113,7 @@
gv2 = builder.genop2('int_le', gv_i1, gv1)
loop_builder = builder.jump_if_true(gv2, [gv_result1, gv_i1, gv1])
builder.finish_and_return(f1_token, gv_result1)
+ loop_builder.start_writing()
loop_builder.finish_and_goto([gv_result1, gv_i1, gv1], loopblock)
builder.end()
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py Mon Jan 8 15:01:53 2007
@@ -102,9 +102,10 @@
that is taken if gv_condition is false and return the new
builder.
- The current builder stays open, and it must be closed before
- the fresh builder is used at all, to make the backend\'s life
- easier.'''
+ The current builder stays open. To make the backend\'s life
+ easier it must be closed before the fresh builder is used at
+ all, and the first thing to call on the latter is
+ start_writing().'''
def jump_if_true(self, gv_condition, args_for_jump_gv):
'''See above, with the obvious difference :)'''
@@ -153,14 +154,15 @@
'''Optional method: prints or logs the position of the generated code
along with the given msg.
'''
- def pause(self):
+ def pause_writing(self, args_gv):
'''Optional method: Called when the builder will not be used for a
while. This allows the builder to free temporary resources needed
during code generation. The next call to the builder will have to be
- to enter_next_block, finish_and_got, finish_and_return or resume.
+ to start_writing().
'''
- def resume(self):
- 'Resumes a paused builder.'
+ def start_writing(self):
+ '''Start a builder returned by jump_if_xxx(), or resumes a paused
+ builder.'''
class GenLabel(object):
'''A "smart" label. Represents an address of the start of a basic
From pedronis at codespeak.net Mon Jan 8 15:28:43 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Mon, 8 Jan 2007 15:28:43 +0100 (CET)
Subject: [pypy-svn] r36274 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070108142843.8E3CB1007A@code0.codespeak.net>
Author: pedronis
Date: Mon Jan 8 15:27:57 2007
New Revision: 36274
Modified:
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
make the first virtualizable struct test pass. We really need to use a different subclass of VirtualStruct
that allows to pass around the original virtualizable struct too.
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Mon Jan 8 15:27:57 2007
@@ -208,18 +208,18 @@
annhelper = self.annhelper
rgenop = self.RGenOp()
- argcolors = []
+ args_specification = []
portal_args_s = []
for v in portalgraph.getargs()[1:]:
r = self.bindingrepr(v)
if isinstance(r, GreenRepr):
- color = "green"
+ arg_spec = "green", None, None
portal_args_s.append(annmodel.lltype_to_annotation(
r.lowleveltype))
else:
- color = "red"
+ arg_spec = "red", r.residual_args_collector(), r.arg_redbox_maker()
portal_args_s.append(self.s_RedBox)
- argcolors.append(color)
+ args_specification.append(arg_spec)
tsportalgraph = portalgraph
# patch the shared portal pointer
@@ -235,7 +235,7 @@
RESTYPE = FUNC.RESULT
reskind = rgenop.kindToken(RESTYPE)
boxbuilder = rvalue.ll_redboxbuilder(RESTYPE)
- argcolors = unrolling_iterable(argcolors)
+ args_specification = unrolling_iterable(args_specification)
fresh_jitstate = self.ll_fresh_jitstate
finish_jitstate = self.ll_finish_jitstate
@@ -249,7 +249,7 @@
def readportal(*args):
i = 0
key = ()
- for color in argcolors:
+ for color, _, _ in args_specification:
if color == "green":
x = args[i]
if isinstance(lltype.typeOf(x), lltype.Ptr):
@@ -272,14 +272,14 @@
i = 0
key = ()
residualargs = ()
- for color in argcolors:
+ for color, collect_residual_args, _ in args_specification:
if color == "green":
x = args[i]
if isinstance(lltype.typeOf(x), lltype.Ptr):
x = llmemory.cast_ptr_to_adr(x)
key = key + (x,)
else:
- residualargs = residualargs + (args[i],)
+ residualargs = residualargs + collect_residual_args(args[i])
i = i + 1
cache = state.cache
try:
@@ -291,7 +291,7 @@
"generated")
cache[key] = gv_generated
i = 0
- for color in argcolors:
+ for color, _, make_arg_redbox in args_specification:
if color == "green":
llvalue = args[0]
args = args[1:]
@@ -299,12 +299,8 @@
else:
llvalue = args[0]
args = args[1:]
- TYPE = lltype.typeOf(llvalue)
- kind = rgenop.kindToken(TYPE)
- boxcls = rvalue.ll_redboxcls(TYPE)
- gv_arg = inputargs_gv[i]
- box = boxcls(kind, gv_arg)
- i += 1
+ box = make_arg_redbox(inputargs_gv, i)
+ i += make_arg_redbox.consumes
portal_ts_args += (box,)
top_jitstate = fresh_jitstate(builder)
@@ -335,16 +331,16 @@
s_funcptrlist)
TYPES = [v.concretetype for v in origportalgraph.getargs()]
- argcolorandtypes = unrolling_iterable(zip(argcolors,
+ argspecandtypes = unrolling_iterable(zip(args_specification,
TYPES))
fetch_global_excdata = self.fetch_global_excdata
- def portalreentry(jitstate, *args):
+ def portalreentry(jitstate, *args): # xxx
i = 0
key = ()
curbuilder = jitstate.curbuilder
args_gv = []
- for color in argcolors:
+ for color, _, _ in args_specification:
if color == "green":
x = args[i]
if isinstance(lltype.typeOf(x), lltype.Ptr):
@@ -364,7 +360,7 @@
"generated")
cache[key] = gv_generated
i = 0
- for color, T in argcolorandtypes:
+ for (color, _, _), T in argspecandtypes:
if color == "green":
llvalue = args[0]
args = args[1:]
@@ -451,8 +447,11 @@
ha = self.annotator
args_hs, hs_res = self.get_sig_hs(ha.translator.graphs[0])
RESTYPE = originalconcretetype(hs_res)
- ARGS = [originalconcretetype(hs_arg) for hs_arg in args_hs
- if not hs_arg.is_green()]
+ args_r = [self.getrepr(hs_arg) for hs_arg in args_hs
+ if not hs_arg.is_green()]
+ ARGS = []
+ for r_arg in args_r:
+ ARGS += r_arg.residual_argtypes()
return lltype.FuncType(ARGS, RESTYPE)
def make_new_lloplist(self, block):
@@ -671,8 +670,16 @@
[ts.s_JITState],
[v_jitstate ],
ts.s_RedBox)
- # non virtual case
+ # virtualizable access read
PTRTYPE = originalconcretetype(hop.args_s[0])
+ if PTRTYPE.TO._hints.get('virtualizable', False):
+ # xxx optimisation: do this folding already at hint-annotation time!
+ if hop.args_v[1].value == 'access':
+ ACCESSPTR = PTRTYPE.TO.access
+ access_repr = self.getredrepr(ACCESSPTR)
+ return hop.inputconst(access_repr, lltype.nullptr(ACCESSPTR.TO))
+
+ # non virtual case
v_argbox, c_fieldname = hop.inputargs(self.getredrepr(PTRTYPE),
green_void_repr)
v_argbox = hop.llops.as_ptrredbox(v_argbox)
@@ -1441,6 +1448,23 @@
self.original_concretetype = original_concretetype
self.lowleveltype = hrtyper.r_RedBox.lowleveltype
self.hrtyper = hrtyper
+ self.build_portal_arg_helpers()
+
+ def build_portal_arg_helpers(self):
+ def collect_residual_args(v):
+ return (v,)
+ self.collect_residual_args = collect_residual_args
+
+ TYPE = self.original_concretetype
+ kind = self.hrtyper.RGenOp.kindToken(TYPE)
+ boxcls = rvalue.ll_redboxcls(TYPE)
+
+ def make_arg_redbox(inputargs_gv, i):
+ gv_arg = inputargs_gv[i]
+ box = boxcls(kind, gv_arg)
+ return box
+ self.make_arg_redbox = make_arg_redbox
+ make_arg_redbox.consumes = 1
## def get_genop_var(self, v, llops):
## ts = self.hrtyper
@@ -1459,19 +1483,78 @@
def residual_values(self, ll_value):
return [ll_value]
+ def residual_argtypes(self):
+ return [self.original_concretetype]
+
+ def residual_args_collector(self):
+ return self.collect_residual_args
+
+ def arg_redbox_maker(self):
+ return self.make_arg_redbox
class RedStructRepr(RedRepr):
typedesc = None
- def create(self, hop):
- ts = self.hrtyper
+ def build_portal_arg_helpers(self):
+ T = self.original_concretetype.TO
+ if not T._hints.get('virtualizable', False):
+ RedRepr.build_portal_arg_helpers(self)
+ return
+
+ names = unrolling_iterable([name for name in T._names if name != 'access'])
+ def collect_residual_args(v):
+ t = ()
+ for name in names:
+ t = t + (getattr(v, name),) # xxx need to use access ?
+ return t
+ self.collect_residual_args = collect_residual_args
+
+ TYPE = self.original_concretetype
+ kind = self.hrtyper.RGenOp.kindToken(TYPE)
+ boxcls = rvalue.ll_redboxcls(TYPE)
+
+ typedesc = self.gettypedesc()
+
+ def make_arg_redbox(inputargs_gv, i):
+ box = typedesc.factory()
+ j = 1
+ content = box.content
+ assert isinstance(content, rcontainer.VirtualStruct)
+ content_boxes = content.content_boxes
+ for name in names:
+ content_boxes[j].genvar = inputargs_gv[i]
+ j = j + 1
+ i += 1
+ return box
+ self.make_arg_redbox = make_arg_redbox
+ make_arg_redbox.consumes = len(T._names)-1
+
+ def gettypedesc(self):
if self.typedesc is None:
+ ts = self.hrtyper
T = self.original_concretetype.TO
self.typedesc = rcontainer.StructTypeDesc(ts.RGenOp, T)
- v_ptrbox = hop.llops.genmixlevelhelpercall(self.typedesc.ll_factory,
+ return self.typedesc
+
+ def create(self, hop):
+ ts = self.hrtyper
+ typedesc = self.gettypedesc()
+ v_ptrbox = hop.llops.genmixlevelhelpercall(typedesc.ll_factory,
[], [], ts.s_PtrRedBox)
return hop.llops.as_redbox(v_ptrbox)
+ def residual_argtypes(self):
+ T = self.original_concretetype.TO
+ if T._hints.get('virtualizable', False):
+ argtypes = []
+ getredrepr = self.hrtyper.getredrepr
+ for name in T._names:
+ if name == 'access':
+ continue
+ FIELDTYPE = getattr(T, name)
+ argtypes += getredrepr(FIELDTYPE).residual_argtypes()
+ return argtypes
+ return [self.original_concretetype]
##class VoidRedRepr(Repr):
## def __init__(self, hrtyper):
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Mon Jan 8 15:27:57 2007
@@ -6,7 +6,6 @@
class TestVirtualizable(PortalTest):
def test_simple_explicit(self):
- py.test.skip("WIP")
XY = lltype.GcForwardReference()
GETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY)], lltype.Signed))
SETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY), lltype.Signed],
From guido at codespeak.net Mon Jan 8 15:38:52 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 15:38:52 +0100 (CET)
Subject: [pypy-svn] r36276 - pypy/dist/pypy/tool/build
Message-ID: <20070108143852.B2C2B1007F@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 15:38:51 2007
New Revision: 36276
Modified:
pypy/dist/pypy/tool/build/metaserver.py
Log:
(cfbolz, guido) only mailing log on errors
Modified: pypy/dist/pypy/tool/build/metaserver.py
==============================================================================
--- pypy/dist/pypy/tool/build/metaserver.py (original)
+++ pypy/dist/pypy/tool/build/metaserver.py Mon Jan 8 15:38:51 2007
@@ -241,7 +241,8 @@
self.config.projectname,
buildpath.error.__class__.__name__)
body = ('There was an error during the compilation you '
- 'requested. The log can be found below.')
+ 'requested. The log can be found below.'
+ '\n\n%s' % (buildpath.log,))
else:
subject = '%s - compilation done' % (
self.config.projectname,)
@@ -254,8 +255,6 @@
'Subject: %s' % (subject,),
'',
body,
- '',
- buildpath.log,
])
server = smtplib.SMTP(self.config.mailhost,
self.config.mailport)
From arigo at codespeak.net Mon Jan 8 16:17:39 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 16:17:39 +0100 (CET)
Subject: [pypy-svn] r36279 - in pypy/branch/jit-codegen-refactor/pypy/jit:
codegen codegen/llgraph timeshifter
Message-ID: <20070108151739.2124410076@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 16:17:37 2007
New Revision: 36279
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py
pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py
Log:
(mwh, arigo)
Finished adapting test_rtimeshift to the new rgenop interface.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 16:17:37 2007
@@ -211,8 +211,10 @@
def pause_writing(self, args_gv):
lnk = llimpl.closeblock1(self.b)
b2 = llimpl.closelinktofreshblock(lnk, args_gv)
- self.later_block = b2
self._close()
+ later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
+ later_builder.later_block = b2
+ return later_builder
def show_incremental_progress(self):
llimpl.show_incremental_progress(self.gv_f)
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/model.py Mon Jan 8 16:17:37 2007
@@ -156,10 +156,12 @@
'''
def pause_writing(self, args_gv):
'''Optional method: Called when the builder will not be used for a
- while. This allows the builder to free temporary resources needed
- during code generation. The next call to the builder will have to be
- to start_writing().
+ while. This allows the builder to be freed. The pause_writing()
+ method returns the next builder, on which you will have to call
+ start_writing() before you continue.
'''
+ return self
+
def start_writing(self):
'''Start a builder returned by jump_if_xxx(), or resumes a paused
builder.'''
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py Mon Jan 8 16:17:37 2007
@@ -308,18 +308,12 @@
resuming.mergesleft -= 1
def guard_global_merge(jitstate, resumepoint):
- jitstate.curbuilder.pause()
+ jitstate.pause()
dispatchqueue = jitstate.frame.dispatchqueue
jitstate.next = dispatchqueue.global_merge_chain
dispatchqueue.global_merge_chain = jitstate
jitstate.resumepoint = resumepoint
-def enter_block(jitstate):
- incoming = []
- memo = rvalue.enter_block_memo()
- jitstate.enter_block(incoming, memo)
- enter_next_block(jitstate, incoming)
-
def split(jitstate, switchredbox, resumepoint, *greens_gv):
exitgvar = switchredbox.getgenvar(jitstate.curbuilder)
if exitgvar.is_const:
@@ -340,6 +334,8 @@
return True
def collect_split(jitstate_chain, resumepoint, *greens_gv):
+ # assumes that the head of the jitstate_chain is ready for writing,
+ # and all the other jitstates in the chain are paused
greens_gv = list(greens_gv)
pending = jitstate_chain
resuming = jitstate_chain.resuming
@@ -389,12 +385,12 @@
if dispatchqueue.split_chain is not None:
jitstate = dispatchqueue.split_chain
dispatchqueue.split_chain = jitstate.next
- enter_block(jitstate)
+ jitstate.curbuilder.start_writing()
return jitstate
elif dispatchqueue.global_merge_chain is not None:
jitstate = dispatchqueue.global_merge_chain
dispatchqueue.global_merge_chain = jitstate.next
- jitstate.curbuilder.resume()
+ jitstate.curbuilder.start_writing()
return jitstate
else:
oldjitstate.resumepoint = -1
@@ -442,7 +438,7 @@
def save_return(jitstate):
# add 'jitstate' to the chain of return-jitstates
- jitstate.curbuilder.pause()
+ jitstate.pause()
dispatchqueue = jitstate.frame.dispatchqueue
jitstate.next = dispatchqueue.return_chain
dispatchqueue.return_chain = jitstate
@@ -874,6 +870,10 @@
locals_gv = [redbox.genvar for redbox in incoming]
return locals_gv
+ def pause(self):
+ locals_gv = self.get_locals_gv()
+ self.curbuilder = self.curbuilder.pause_writing(locals_gv)
+
def residual_ll_exception(self, ll_evalue):
ll_etype = ll_evalue.typeptr
@@ -926,13 +926,13 @@
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
- jitstate.curbuilder.resume()
+ jitstate.curbuilder.start_writing()
res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
return_marker,
force_merge=force_merge)
if res is False: # not finished
if still_pending:
- still_pending.curbuilder.pause()
+ still_pending.pause()
jitstate.next = still_pending
still_pending = jitstate
@@ -942,16 +942,19 @@
if return_chain is not None:
return_cache = {}
still_pending = None
+ was_paused = False
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
- jitstate.curbuilder.resume()
+ if was_paused:
+ jitstate.curbuilder.start_writing()
+ was_paused = True # only the head of the list was *not* paused
res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
return_marker,
force_merge=force_merge)
if res is False: # not finished
if still_pending:
- still_pending.curbuilder.pause()
+ still_pending.pause()
jitstate.next = still_pending
still_pending = jitstate
return still_pending
@@ -1010,4 +1013,7 @@
while jitstate is not None:
leave_frame(jitstate)
jitstate = jitstate.next
- return return_chain # a jitstate, which is the head of the chain
+ # return the jitstate which is the head of the chain,
+ # ready for further writing
+ return_chain.curbuilder.start_writing()
+ return return_chain
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/transform.py Mon Jan 8 16:17:37 2007
@@ -433,6 +433,7 @@
if self.graphcolor == 'gray':
self.genop(block, 'save_locals', [])
elif self.graphcolor == 'yellow':
+ self.genop(block, 'save_locals', [])
self.genop(block, 'save_greens', [v_retbox])
elif self.graphcolor == 'red':
self.genop(block, 'save_locals', [v_retbox])
From mwh at codespeak.net Mon Jan 8 16:32:25 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Mon, 8 Jan 2007 16:32:25 +0100 (CET)
Subject: [pypy-svn] r36280 - in pypy/dist/pypy/translator/c: . test
Message-ID: <20070108153225.8144010076@code0.codespeak.net>
Author: mwh
Date: Mon Jan 8 16:32:23 2007
New Revision: 36280
Modified:
pypy/dist/pypy/translator/c/node.py
pypy/dist/pypy/translator/c/primitive.py
pypy/dist/pypy/translator/c/test/test_genc.py
Log:
NaN support in genc.
testing on windows might be a good idea.
Modified: pypy/dist/pypy/translator/c/node.py
==============================================================================
--- pypy/dist/pypy/translator/c/node.py (original)
+++ pypy/dist/pypy/translator/c/node.py Mon Jan 8 16:32:23 2007
@@ -10,7 +10,7 @@
from pypy.translator.c.support import USESLOTS # set to False if necessary while refactoring
from pypy.translator.c.support import cdecl, forward_cdecl, somelettersfrom
from pypy.translator.c.support import c_char_array_constant
-from pypy.translator.c.primitive import PrimitiveType, isinf
+from pypy.translator.c.primitive import PrimitiveType, isinf, isnan
from pypy.translator.c import extfunc
@@ -572,7 +572,7 @@
node = db.getcontainernode(value._obj)
expr = 'NULL /*%s*/' % node.name
node.where_to_copy_me.append('&%s' % access_expr)
- elif typeOf(value) == Float and isinf(value):
+ elif typeOf(value) == Float and (isinf(value) or isnan(value)):
db.late_initializations.append(('%s' % access_expr, db.get(value)))
expr = '0.0 /* patched later by %sinfinity */' % (
'-+'[value > 0])
Modified: pypy/dist/pypy/translator/c/primitive.py
==============================================================================
--- pypy/dist/pypy/translator/c/primitive.py (original)
+++ pypy/dist/pypy/translator/c/primitive.py Mon Jan 8 16:32:23 2007
@@ -71,12 +71,20 @@
def isinf(x):
return x != 0.0 and x / 2 == x
+# To get isnan, working x-platform and both on 2.3 and 2.4, is a
+# horror. I think this works (for reasons I don't really want to talk
+# about), and probably when implemented on top of pypy, too.
+def isnan(v):
+ return v != v*1.0 or (v == 1.0 and v == 2.0)
+
def name_float(value, db):
if isinf(value):
if value > 0:
return '(Py_HUGE_VAL)'
else:
return '(-Py_HUGE_VAL)'
+ elif isnan(value):
+ return '(Py_HUGE_VAL/Py_HUGE_VAL)'
else:
return repr(value)
Modified: pypy/dist/pypy/translator/c/test/test_genc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_genc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_genc.py Mon Jan 8 16:32:23 2007
@@ -248,6 +248,26 @@
res = f1(3)
assert res == 1.5
+def test_nan():
+ from pypy.translator.c.primitive import isnan, isinf
+ inf = 1e300 * 1e300
+ assert isinf(inf)
+ nan = inf/inf
+ assert isnan(nan)
+
+ l = [nan]
+ def f():
+ return nan
+ f1 = compile(f, [])
+ res = f1()
+ assert isnan(res)
+
+ def g(x):
+ return l[x]
+ g2 = compile(g, [int])
+ res = g2(0)
+ assert isnan(res)
+
def test_x():
class A:
pass
@@ -343,4 +363,3 @@
s = t.buildannotator().build_types(f, [])
rtyper = t.buildrtyper(type_system="lltype")
rtyper.specialize()
-
From santagada at codespeak.net Mon Jan 8 17:03:42 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Mon, 8 Jan 2007 17:03:42 +0100 (CET)
Subject: [pypy-svn] r36288 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070108160342.9AA6C10075@code0.codespeak.net>
Author: santagada
Date: Mon Jan 8 17:03:39 2007
New Revision: 36288
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsparser.py
pypy/dist/pypy/lang/js/test/test_parser.py
Log:
(santagada, antonio, carl) new parser for the output of narcissus
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Mon Jan 8 17:03:39 2007
@@ -1,6 +1,7 @@
from pypy.lang.js.jsparser import parse
from pypy.lang.js.jsobj import *
+from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal
class Node(object):
# TODO Add line info for debug
@@ -42,14 +43,12 @@
def load_source(self, script_source):
"""load a source script text to the interpreter"""
- temp_dict = parse(script_source)
- #import pprint
- #pprint.pprint(temp_dict)
- self.script = from_dict(temp_dict)
+ temp_tree = parse(script_source)
+ self.script = from_tree(temp_tree)
def append_source(self, script_source):
- temp_dict = parse(script_source)
- newscript = from_dict(temp_dict)
+ temp_tree = parse(script_source)
+ newscript = from_tree(temp_tree)
self.script.append_script(newscript)
def run(self):
@@ -458,144 +457,150 @@
while self.condition.call(ctx).ToBoolean():
self.body.call(ctx)
-def getlist(d):
- if 'length' not in d:
+def getlist(t):
+ item = gettreeitem(t, 'length')
+ if item is None:
return []
- lgt = int(d['length'])
- output = [from_dict(d[str(i)]) for i in range(lgt)]
+ lgt = int(item.additional_info)
+ output = [from_tree(gettreeitem(t, str(i))) for i in range(lgt)]
return output
-
-def build_interpreter(d):
- return from_dict(d)
-
-# FIXME: Continue the translation from if/elif to this dict map
-build_map = {'ARRAY_INIT':Array,
- 'ASSIGN': Assign,
- 'BLOCK': Block}
-
-def from_dict_map(d):
- if d is None:
- return d
- try:
- build_map[d['type']](d)
- except KeyError,e:
- raise NotImplementedError("Don't know how to handle %s" %(d['type'],))
-
-
-def from_dict(d):
- if d is None:
- return d
- tp = d['type']
+def gettreeitem(t, name):
+ for x in t.children:
+ if x.children[0].additional_info == name:
+ return x.children[1]
+ return
+
+def from_tree(t):
+ if t is None:
+ return
+ tp = gettreeitem(t, 'type').additional_info
if tp == 'ARRAY_INIT':
return Array(getlist(d))
elif tp == 'ASSIGN':
- return Assign(from_dict(d['0']), from_dict(d['1']))
+ return Assign(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'BLOCK':
- return Block(getlist(d))
+ return Block(getlist(t))
elif tp == 'CALL':
- return Call(from_dict(d['0']), from_dict(d['1']))
+ return Call(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'COMMA':
- return Comma(from_dict(d['0']),from_dict(d['1']))
+ return Comma(from_tree(gettreeitem(t, '0')),from_tree(gettreeitem(t, '1')))
elif tp == 'DOT':
- return Dot(from_dict(d['0']), from_dict(d['1']))
+ return Dot(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'EQ':
- return Eq(from_dict(d['0']), from_dict(d['1']))
+ return Eq(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'OR':
- return Or(from_dict(d['0']), from_dict(d['1']))
+ return Or(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'AND':
- return And(from_dict(d['0']), from_dict(d['1']))
+ return And(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'FUNCTION':
- name = d.get('name', '')
- body = from_dict(d['body'])
- if d['params'] == '':
+ name = gettreeitem(t, 'name')
+ if name is not None:
+ name = name.additional_info
+ body = from_tree(gettreeitem(t, 'body'))
+ if gettreeitem(t, 'params').additional_info == '':
params = []
else:
- params = d['params'].split(',')
+ params = gettreeitem(t, 'params').additional_info.split(',')
f = Function(name, params, body)
return f
elif tp == 'GROUP':
- return Group(from_dict(d['0']))
+ return Group(from_tree(gettreeitem(t, '0')))
elif tp == 'GE':
- return Ge(from_dict(d['0']), from_dict(d['1']))
+ return Ge(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'GT':
- return Gt(from_dict(d['0']), from_dict(d['1']))
+ return Gt(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'IDENTIFIER':
- return Identifier(d['value'], from_dict(d.get('initializer', None)))
+ return Identifier(gettreeitem(t, 'value').additional_info, from_tree(gettreeitem(t, 'initializer')))
elif tp == 'IF':
- condition = from_dict(d['condition'])
- if d['thenPart'] == 'null':
+ condition = from_tree(gettreeitem(t, 'condition'))
+ thenPart = gettreeitem(t, 'thenPart')
+ if isinstance(thenPart, Nonterminal):
+ thenPart = from_tree(thenPart)
+ else:
thenPart = Undefined()
+
+ elsePart = gettreeitem(t, 'elsePart')
+ if isinstance(elsePart, Nonterminal):
+ elsePart = from_tree(elsePart)
else:
- thenPart = from_dict(d['thenPart'])
- if d['elsePart'] == 'null':
elsePart = Undefined()
- else:
- elsePart = from_dict(d['elsePart'])
return If(condition,thenPart,elsePart)
elif tp == 'IN':
- return In(from_dict(d['0']), from_dict(d['1']))
+ return In(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'INDEX':
- return Index(from_dict(d['0']), from_dict(d['1']))
+ return Index(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'LIST':
- return List(getlist(d))
+ return List(getlist(t))
elif tp == 'LE':
- return Le(from_dict(d['0']), from_dict(d['1']))
+ return Le(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'LT':
- return Lt(from_dict(d['0']), from_dict(d['1']))
+ return Lt(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'MINUS':
- return Minus(from_dict(d['0']), from_dict(d['1']))
+ return Minus(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NE':
- return Ne(from_dict(d['0']), from_dict(d['1']))
+ return Ne(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NEW':
- return New(d['0']['value'])
+ return New(gettreeitem(gettreeitem(t, '0'),'value').additional_info)
elif tp == 'NUMBER':
- return Number(float(d['value']))
+ return Number(float(gettreeitem(t, 'value').additional_info))
elif tp == 'OBJECT_INIT':
- return ObjectInit(getlist(d))
+ return ObjectInit(getlist(t))
elif tp == 'PLUS':
- return Plus(from_dict(d['0']), from_dict(d['1']))
+ return Plus(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'PROPERTY_INIT':
- return PropertyInit(from_dict(d['0']), from_dict(d['1']))
+ return PropertyInit(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'RETURN':
- return Return(from_dict(d['value']))
+ return Return(from_tree(gettreeitem(t, 'value')))
elif tp == 'SCRIPT':
- if isinstance(d['funDecls'], dict):
- func_decl = [from_dict(d['funDecls']),]
+ print "*funDecls:'' ", gettreeitem(t, 'funDecls') == ''
+ f = gettreeitem(t, 'funDecls')
+ print f.symbol
+ if f.symbol == "dict":
+ func_decl = [from_tree(f),]
+ elif f.symbol == "list":
+ func_decl = [from_tree(x) for x in f.children]
else:
- func_decl = [from_dict(x) for x in d['funDecls']]
+ func_decl = []
- if isinstance(d['varDecls'], dict):
- var_decl = [from_dict(d['varDecls']),]
+ v = gettreeitem(t, 'varDecls')
+ print v.symbol
+ if v.symbol == "dict":
+ var_decl = [from_tree(v),]
+ elif v.symbol == "list":
+ var_decl = [from_tree(x) for x in v.children]
else:
- var_decl = [from_dict(x) for x in d['varDecls']]
- return Script(getlist(d), var_decl, func_decl)
+ var_decl = []
+
+ return Script(getlist(t), var_decl, func_decl)
elif tp == 'SEMICOLON':
- if d['expression'] == 'null':
+ if gettreeitem(t, 'expression') == 'null':
return Semicolon()
- return Semicolon(from_dict(d['expression']))
+ return Semicolon(from_tree(gettreeitem(t, 'expression')))
elif tp == 'STRING':
- return String(d['value'])
+ return String(gettreeitem(t, 'value').additional_info)
elif tp == 'THIS':
- return Identifier(d['value'])
+ return Identifier(gettreeitem(t, 'value').additional_info)
elif tp == 'THROW':
- return Throw(from_dict(d['exception']))
+ return Throw(from_tree(gettreeitem(t, 'exception')))
elif tp == 'TRY':
finallyblock = None
catchblock = None
catchparam = ''
- if 'finallyBlock' in d:
- finallyblock = from_dict(d['finallyBlock'])
- if 'catchClauses' in d:
+ final = gettreeitem(t, 'finallyBlock')
+ if final is not None:
+ finallyblock = from_tree(final)
+ catch = gettreeitem(t, 'catchClauses')
+ if catch is not None:
#multiple catch clauses is a spidermonkey extension
- catchblock = from_dict(d['catchClauses']['block'])
- catchparam = d['catchClauses']['varName']
- return Try(from_dict(d['tryBlock']), catchblock, finallyblock, catchparam)
+ catchblock = from_tree(gettreeitem(catch, 'block'))
+ catchparam = gettreeitem(catch, 'varName').additional_info
+ return Try(from_tree(gettreeitem(t, 'tryBlock')), catchblock, finallyblock, catchparam)
elif tp == 'VAR':
- return Vars(getlist(d))
+ return Vars(getlist(t))
elif tp == 'WHILE':
- body = from_dict(d['body'])
- condition = from_dict(d['condition'])
+ body = from_tree(gettreeitem(t, 'body'))
+ condition = from_tree(gettreeitem(t, 'condition'))
return While(condition, body)
else:
raise NotImplementedError("Dont know how to handler %s" % tp)
Modified: pypy/dist/pypy/lang/js/jsparser.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsparser.py (original)
+++ pypy/dist/pypy/lang/js/jsparser.py Mon Jan 8 17:03:39 2007
@@ -8,6 +8,8 @@
import py
import re
from subprocess import Popen, PIPE, STDOUT
+from pypy.rlib.parsing.ebnfparse import parse_ebnf, make_parse_function
+from pypy.rlib.parsing.ebnfparse import Symbol
class JsSyntaxError(Exception):
pass
@@ -27,15 +29,35 @@
raise JsSyntaxError(retval)
return retval
+def unquote(t):
+ if isinstance(t, Symbol):
+ if t.symbol == "QUOTED_STRING":
+ t.additional_info = t.additional_info.strip("'")
+ else:
+ for i in t.children:
+ unquote(i)
+
def parse(code_string):
read_code = read_js_output(code_string)
output = read_code.split(os.linesep)
#print '\n'.join(output)
- try:
- code = eval("\n".join(output))
- except (SyntaxError, NameError):
- for num, line in enumerate(output):
- print "%d: %s" % (num + 1, line)
- open("/tmp/out", "w").write("\n".join(output))
- raise
- return code
+ t = parse_bytecode(output)
+ unquote(t)
+ #print "-----------------\n",t
+ #print "-----------------\n",t.children[0].children[0].additional_info
+ return t
+
+def parse_bytecode(bytecode):
+ regexs, rules, ToAST = parse_ebnf("""
+ QUOTED_STRING: "'[^\\']*'";
+ IGNORE: " |\n";
+ data: | | ;
+ dict: ["{"] (dictentry [","])* dictentry ["}"];
+ dictentry: QUOTED_STRING [":"] data;
+ list: ["["] (data [","])* data ["]"];
+""")
+ parse = make_parse_function(regexs, rules, eof=True)
+ t = parse("\n".join(bytecode))
+ #print "0000000",t
+ return ToAST().transform(t)
+
Modified: pypy/dist/pypy/lang/js/test/test_parser.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_parser.py (original)
+++ pypy/dist/pypy/lang/js/test/test_parser.py Mon Jan 8 17:03:39 2007
@@ -2,7 +2,7 @@
from pypy.lang.js.test.test_interp import js_is_on_path
import py
-
+py.test.skip("FIX ME: new tests for the new parser")
js_is_on_path()
From pedronis at codespeak.net Mon Jan 8 17:33:28 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Mon, 8 Jan 2007 17:33:28 +0100 (CET)
Subject: [pypy-svn] r36294 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070108163328.8062E10079@code0.codespeak.net>
Author: pedronis
Date: Mon Jan 8 17:33:23 2007
New Revision: 36294
Modified:
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/test/test_portal.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
start using a special subclass of VirtualStruct - VirtualizableStruct - for virtualizable structs.
Make sure that the original virtualizable struct from the non-jit world is carried around.
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Mon Jan 8 17:33:23 2007
@@ -1503,7 +1503,7 @@
names = unrolling_iterable([name for name in T._names if name != 'access'])
def collect_residual_args(v):
- t = ()
+ t = (v,)
for name in names:
t = t + (getattr(v, name),) # xxx need to use access ?
return t
@@ -1521,13 +1521,16 @@
content = box.content
assert isinstance(content, rcontainer.VirtualStruct)
content_boxes = content.content_boxes
+ gv_outside = inputargs_gv[i]
+ i += 1
for name in names:
content_boxes[j].genvar = inputargs_gv[i]
j = j + 1
i += 1
+ content_boxes[j].genvar = gv_outside
return box
self.make_arg_redbox = make_arg_redbox
- make_arg_redbox.consumes = len(T._names)-1
+ make_arg_redbox.consumes = len(T._names)
def gettypedesc(self):
if self.typedesc is None:
@@ -1544,17 +1547,16 @@
return hop.llops.as_redbox(v_ptrbox)
def residual_argtypes(self):
+ argtypes = [self.original_concretetype]
T = self.original_concretetype.TO
if T._hints.get('virtualizable', False):
- argtypes = []
getredrepr = self.hrtyper.getredrepr
for name in T._names:
if name == 'access':
continue
FIELDTYPE = getattr(T, name)
argtypes += getredrepr(FIELDTYPE).residual_argtypes()
- return argtypes
- return [self.original_concretetype]
+ return argtypes
##class VoidRedRepr(Repr):
## def __init__(self, hrtyper):
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Mon Jan 8 17:33:23 2007
@@ -82,6 +82,9 @@
self.immutable = TYPE._hints.get('immutable', False)
self.noidentity = TYPE._hints.get('noidentity', False)
+ if TYPE._hints.get('virtualizable', False):
+ self.__class__ = VirtualizableStructTypeDesc
+
if self.immutable and self.noidentity:
descs = unrolling_iterable(fielddescs)
def materialize(rgenop, boxes):
@@ -117,6 +120,20 @@
def compact_repr(self): # goes in ll helper names
return "Desc_%s" % (self.TYPE._short_name(),)
+class VirtualizableStructTypeDesc(StructTypeDesc):
+
+ def factory(self):
+ vstruct = VirtualizableStruct(self)
+ vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
+ for desc in self.fielddescs]
+ outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
+ # xxx set outsidebox.genvar
+ vstruct.content_boxes.append(outsidebox)
+ box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
+ box.content = vstruct
+ vstruct.ownbox = box
+ return box
+
# XXX basic field descs for now
class FieldDesc(object):
__metaclass__ = cachedtype
@@ -306,6 +323,12 @@
def op_getsubstruct(self, jitstate, fielddesc):
return self.ownbox
+class VirtualizableStruct(VirtualStruct):
+
+ def force_runtime_container(self, builder):
+ assert 0, "not implemented for now"
+
+
# ____________________________________________________________
class FrozenPartialDataStruct(AbstractContainer):
Modified: pypy/dist/pypy/jit/timeshifter/test/test_portal.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_portal.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_portal.py Mon Jan 8 17:33:23 2007
@@ -88,8 +88,7 @@
res = llinterp.eval_graph(self.maingraph, main_args)
return res
- def check_insns(self, expected=None, **counts):
- # XXX only works if the portal is the same as the main
+ def get_residual_graph(self):
llinterp = LLInterpreter(self.rtyper)
if self.main_is_portal:
residual_graph = llinterp.eval_graph(self.readportalgraph,
@@ -98,7 +97,11 @@
residual_graphs = llinterp.eval_graph(self.readallportalsgraph, [])
assert residual_graphs.ll_length() == 1
residual_graph = residual_graphs.ll_getitem_fast(0)._obj.graph
+ return residual_graph
+ def check_insns(self, expected=None, **counts):
+ # XXX only works if the portal is the same as the main
+ residual_graph = self.get_residual_graph()
self.insns = summary(residual_graph)
if expected is not None:
assert self.insns == expected
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Mon Jan 8 17:33:23 2007
@@ -47,4 +47,8 @@
res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
assert res == 42
- self.check_insns(getfield=0) # maybe?
+ self.check_insns(getfield=0)
+ residual_graph = self.get_residual_graph()
+ assert len(residual_graph.startblock.inputargs) == 3
+ assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
+ [lltype.Ptr(XY), lltype.Signed, lltype.Signed])
From antocuni at codespeak.net Mon Jan 8 17:58:42 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 8 Jan 2007 17:58:42 +0100 (CET)
Subject: [pypy-svn] r36297 - in pypy/dist/pypy: rpython/memory/gctransform
translator
Message-ID: <20070108165842.3696210079@code0.codespeak.net>
Author: antocuni
Date: Mon Jan 8 17:58:39 2007
New Revision: 36297
Modified:
pypy/dist/pypy/rpython/memory/gctransform/transform.py
pypy/dist/pypy/translator/unsimplify.py
Log:
(antocuni, arre, pedronis)
Don't take away what you didn't put there.
Modified: pypy/dist/pypy/rpython/memory/gctransform/transform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/transform.py (original)
+++ pypy/dist/pypy/rpython/memory/gctransform/transform.py Mon Jan 8 17:58:39 2007
@@ -5,7 +5,6 @@
from pypy.translator.unsimplify import insert_empty_block
from pypy.translator.unsimplify import insert_empty_startblock
from pypy.translator.unsimplify import starts_with_empty_block
-from pypy.translator.unsimplify import remove_empty_startblock
from pypy.translator.backendopt.support import var_needsgc
from pypy.translator.backendopt import inline
from pypy.translator.backendopt import graphanalyze
@@ -193,8 +192,10 @@
self.links_to_split = {} # link -> vars to pop_alive across the link
# for sanity, we need an empty block at the start of the graph
+ inserted_empty_startblock = False
if not starts_with_empty_block(graph):
insert_empty_startblock(self.translator.annotator, graph)
+ inserted_empty_startblock = True
is_borrowed = self.compute_borrowed_vars(graph)
for block in graph.iterblocks():
@@ -215,8 +216,11 @@
# remove the empty block at the start of the graph, which should
# still be empty (but let's check)
- if starts_with_empty_block(graph):
- remove_empty_startblock(graph)
+ if starts_with_empty_block(graph) and inserted_empty_startblock:
+ old_startblock = graph.startblock
+ graph.startblock.isstartblock = False
+ graph.startblock = graph.startblock.exits[0].target
+ graph.startblock.isstartblock = True
checkgraph(graph)
Modified: pypy/dist/pypy/translator/unsimplify.py
==============================================================================
--- pypy/dist/pypy/translator/unsimplify.py (original)
+++ pypy/dist/pypy/translator/unsimplify.py Mon Jan 8 17:58:39 2007
@@ -51,11 +51,6 @@
and graph.startblock.exitswitch is None
and graph.startblock.exits[0].args == graph.getargs())
-def remove_empty_startblock(graph):
- graph.startblock.isstartblock = False
- graph.startblock = graph.startblock.exits[0].target
- graph.startblock.isstartblock = True
-
def split_block(annotator, block, index, _forcelink=None):
"""return a link where prevblock is the block leading up but excluding the
index'th operation and target is a new block with the neccessary variables
From antocuni at codespeak.net Mon Jan 8 18:10:57 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 8 Jan 2007 18:10:57 +0100 (CET)
Subject: [pypy-svn] r36301 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070108171057.B03FD10079@code0.codespeak.net>
Author: antocuni
Date: Mon Jan 8 18:10:57 2007
New Revision: 36301
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
(antocuni, santagada around)
Make the js interpreter RPythonic: we can now successfully translate
an interpreter that runs a somewhat complex hard-coded snippet. :-)
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Mon Jan 8 18:10:57 2007
@@ -9,17 +9,28 @@
# self.lineno = lineno
pass
-class BinaryOp(Node):
+class Statement(Node):
+ def execute(self, ctx):
+ raise NotImplementedError
+
+class Expression(Statement):
+ def eval(self, ctx):
+ return W_Root()
+
+ def execute(self, ctx):
+ return self.eval(ctx)
+
+class BinaryOp(Expression):
def __init__(self, left, right):
self.left = left
self.right = right
class BinaryComparisonOp(BinaryOp):
"""super class for binary operators"""
- def call(self, ctx):
- s2 = self.left.call(ctx).GetValue()
- s4 = self.right.call(ctx).GetValue()
- return self.decision(s2, s4)
+ def eval(self, ctx):
+ s2 = self.left.eval(ctx).GetValue()
+ s4 = self.right.eval(ctx).GetValue()
+ return self.decision(ctx, s2, s4)
class BinaryLogicOp(BinaryOp):
@@ -35,7 +46,7 @@
self.w_Object = W_Object() #creating Object
self.w_Global = W_Object()
self.w_Global.Prototype = self.w_Object
- self.w_Global.Put('prototype', 'Object')
+ self.w_Global.Put('prototype', W_String('Object'))
self.w_Global.Put('Object', self.w_Object)
self.global_context = global_context(self.w_Global)
if script_source is not None:
@@ -53,7 +64,7 @@
def run(self):
"""run the interpreter"""
- return self.script.call(self.global_context)
+ return self.script.execute(self.global_context)
class PropertyInit(Node):
def __init__(self, name, value):
@@ -64,127 +75,126 @@
return "<%s : %s>"%(str(self.name), str(self.value))
-
-class Undefined(Node):
- def __init__(self):
- pass
-
-
-class Array(Node):
+class Array(Expression):
def __init__(self, items=()):
self.items = items
- def call(self, ctx):
- d = dict(enumerate(self.items))
+ def eval(self, ctx):
+ #d = dict(enumerate(self.items))
+ d = {}
+ for i in range(len(self.items)):
+ d[i] = self.items[i]
return W_Array(d)
-class Assign(Node):
+class Assign(Expression):
def __init__(self, LHSExp, AssignmentExp):
self.LHSExp = LHSExp
self.AssignmentExp = AssignmentExp
- def call(self, ctx):
- print "Assign LHS = ", self.LHSExp
- v1 = self.LHSExp.call(ctx)
- print "Assign Exp = ", self.AssignmentExp
- v3 = self.AssignmentExp.call(ctx).GetValue()
+ def eval(self, ctx):
+ #print "Assign LHS = ", self.LHSExp
+ v1 = self.LHSExp.eval(ctx)
+ #print "Assign Exp = ", self.AssignmentExp
+ v3 = self.AssignmentExp.eval(ctx).GetValue()
v1.PutValue(v3, ctx)
return v3
-class Block(Node):
+class Block(Statement):
def __init__(self, nodes):
self.nodes = nodes
- def call(self, ctx):
+ def execute(self, ctx):
try:
last = w_Undefined
for node in self.nodes:
- last = node.call(ctx)
+ last = node.execute(ctx)
return last
except ExecutionReturned, e:
return e.value
-class Call(Node):
+class Call(Expression):
def __init__(self, identifier, arglist):
self.identifier = identifier
self.arglist = arglist
- def call(self, ctx):
+ def eval(self, ctx):
name = self.identifier.get_literal()
if name == 'print':
- writer(",".join([i.GetValue().ToString() for i in self.arglist.call(ctx)]))
+ writer(",".join([i.GetValue().ToString() for i in self.arglist.get_args(ctx)]))
else:
w_obj = ctx.resolve_identifier(name).GetValue()
- print "arglist = ", self.arglist
- retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.call(ctx)])
+ #print "arglist = ", self.arglist
+ retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.get_args(ctx)])
return retval
class Comma(BinaryOp):
- def call(self, ctx):
- self.left.call(ctx)
- return self.right.call(ctx)
+ def eval(self, ctx):
+ self.left.eval(ctx)
+ return self.right.eval(ctx)
class Dot(BinaryOp):
- def call(self, ctx):
- w_obj = self.left.call(ctx).GetValue().ToObject()
+ def eval(self, ctx):
+ w_obj = self.left.eval(ctx).GetValue().ToObject()
name = self.right.get_literal()
- return Reference(name, w_obj)
+ return W_Reference(name, w_obj)
-class Function(Node):
+class Function(Expression):
def __init__(self, name, params, body):
self.name = name
self.params = params
self.body = body
- def call(self, ctx):
+ def eval(self, ctx):
w_obj = W_FunctionObject(self, ctx)
return w_obj
-class Identifier(Node):
+class Identifier(Expression):
def __init__(self, name, initialiser=None):
self.name = name
self.initialiser = initialiser
+
def __str__(self):
return ""%(str(self.name), str(self.initialiser))
- def call(self, ctx):
+
+ def eval(self, ctx):
if self.initialiser is not None:
ref = ctx.resolve_identifier(self.name)
- ref.PutValue(self.initialiser.call(ctx), ctx)
+ ref.PutValue(self.initialiser.eval(ctx), ctx)
return ctx.resolve_identifier(self.name)
def get_literal(self):
return self.name
-class If(Node):
+class If(Statement):
def __init__(self, condition, thenPart=None, elsePart=None):
self.condition = condition
self.thenPart = thenPart
self.elsePart = elsePart
- def call(self, ctx=None):
- temp = self.condition.call(ctx)
- print "if condition = ", temp
+ def execute(self, ctx=None):
+ temp = self.condition.eval(ctx)
+ #print "if condition = ", temp
if temp.ToBoolean():
- return self.thenPart.call(ctx)
+ return self.thenPart.execute(ctx)
else:
- return self.elsePart.call(ctx)
+ return self.elsePart.execute(ctx)
-class Group(Node):
+class Group(Expression):
def __init__(self, expr):
self.expr = expr
- def call(self, ctx):
- return self.expr.call(ctx)
+ def eval(self, ctx):
+ return self.expr.eval(ctx)
-def ARC(x, y):
+def ARC(ctx, x, y):
"""
Implements the Abstract Relational Comparison x < y
Still not 100% to the spec
"""
# TODO complete the funcion with strings comparison
- s1 = x.ToPrimitive('Number')
- s2 = y.ToPrimitive('Number')
- print "ARC x = %s, y = %s"%(str(s1),str(s2))
+ s1 = x.ToPrimitive(ctx, 'Number')
+ s2 = y.ToPrimitive(ctx, 'Number')
+ #print "ARC x = %s, y = %s"%(str(s1),str(s2))
if not (isinstance(s1, W_String) and isinstance(s2, W_String)):
s4 = s1.ToNumber()
s5 = s2.ToNumber()
@@ -198,48 +208,48 @@
pass
class Or(BinaryLogicOp):
- def call(self, ctx):
- s2 = self.left.call(ctx).GetValue()
+ def eval(self, ctx):
+ s2 = self.left.eval(ctx).GetValue()
if s2.ToBoolean():
return s2
- s4 = self.right.call(ctx).GetValue()
+ s4 = self.right.eval(ctx).GetValue()
return s4
class And(BinaryLogicOp):
- def call(self, ctx):
- s2 = self.left.call(ctx).GetValue()
+ def eval(self, ctx):
+ s2 = self.left.eval(ctx).GetValue()
if not s2.ToBoolean():
return s2
- s4 = self.right.call(ctx).GetValue()
+ s4 = self.right.eval(ctx).GetValue()
return s4
class Ge(BinaryComparisonOp):
- def decision(self, op1, op2):
- s5 = ARC(op1, op2)
+ def decision(self, ctx, op1, op2):
+ s5 = ARC(ctx, op1, op2)
if s5 is None or s5:
return W_Boolean(False)
else:
return W_Boolean(True)
class Gt(BinaryComparisonOp):
- def decision(self, op1, op2):
- s5 = ARC(op2, op1)
+ def decision(self, ctx, op1, op2):
+ s5 = ARC(ctx, op2, op1)
if s5 is None:
return W_Boolean(False)
else:
return W_Boolean(s5)
class Le(BinaryComparisonOp):
- def decision(self, op1, op2):
- s5 = ARC(op2, op1)
+ def decision(self, ctx, op1, op2):
+ s5 = ARC(ctx, op2, op1)
if s5 is None or s5:
return W_Boolean(False)
else:
return W_Boolean(True)
class Lt(BinaryComparisonOp):
- def decision(self, op1, op2):
- s5 = ARC(op1, op2)
+ def decision(self, ctx, op1, op2):
+ s5 = ARC(ctx, op1, op2)
if s5 is None:
return W_Boolean(False)
else:
@@ -254,30 +264,30 @@
return r
class Eq(BinaryComparisonOp):
- def decision(self, op1, op2):
+ def decision(self, ctx, op1, op2):
return W_Boolean(AEC(op1, op2))
class Ne(BinaryComparisonOp):
- def decision(self, op1, op2):
+ def decision(self, ctx, op1, op2):
return W_Boolean(not AEC(op1, op2))
class In(BinaryComparisonOp):
- def decision(self, op1, op2):
+ def decision(self, ctx, op1, op2):
if not isinstance(op2, W_Object):
raise ThrowException("TypeError")
name = op1.ToString()
return W_Boolean(op2.HasProperty(name))
-class Index(Node):
+class Index(Expression):
def __init__(self, left, expr):
self.left = left
self.expr = expr
- def call(self, ctx):
- w_obj = self.left.call(ctx).GetValue()
- w_member = self.expr.call(ctx).GetValue()
+ def eval(self, ctx):
+ w_obj = self.left.eval(ctx).GetValue()
+ w_member = self.expr.eval(ctx).GetValue()
w_obj = w_obj.ToObject()
name = w_member.ToString()
return w_obj.Get(name)
@@ -285,21 +295,22 @@
class List(Node):
def __init__(self, nodes):
self.nodes = nodes
- def call(self, ctx):
- print "nodes = ", self.nodes
- return [node.call(ctx) for node in self.nodes]
+
+ def get_args(self, ctx):
+ #print "nodes = ", self.nodes
+ return [node.eval(ctx) for node in self.nodes]
class Minus(BinaryComparisonOp):
- def decision(self, op1, op2):
+ def decision(self, ctx, op1, op2):
x = op1.ToNumber()
y = op2.ToNumber()
return W_Number(x - y)
-class New(Node):
+class New(Expression):
def __init__(self, identifier):
self.identifier = identifier
- def call(self, ctx):
+ def eval(self, ctx):
obj = W_Object()
#it should be undefined... to be completed
constructor = ctx.resolve_identifier(self.identifier).GetValue()
@@ -307,34 +318,34 @@
constructor.Call(ctx, this = obj)
return obj
-class Number(Node):
+class Number(Expression):
def __init__(self, num):
self.num = num
- def call(self, ctx):
+ def eval(self, ctx):
return W_Number(self.num)
def get_literal(self):
return W_Number(self.num).ToString()
-class ObjectInit(Node):
+class ObjectInit(Expression):
def __init__(self, properties):
self.properties = properties
- def call(self, ctx):
+ def eval(self, ctx):
w_obj = W_Object()
- print "properties = ", self.properties
+ ##print "properties = ", self.properties
for property in self.properties:
name = property.name.get_literal()
- print "prop name = ", name
- w_expr = property.value.call(ctx).GetValue()
+ #print "prop name = ", name
+ w_expr = property.value.eval(ctx).GetValue()
w_obj.Put(name, w_expr)
return w_obj
class Plus(BinaryComparisonOp):
- def decision(self, op1, op2):
- prim_left = op1.ToPrimitive('Number')
- prim_right = op2.ToPrimitive('Number')
+ def decision(self, ctx, op1, op2):
+ prim_left = op1.ToPrimitive(ctx, 'Number')
+ prim_right = op2.ToPrimitive(ctx, 'Number')
if isinstance(prim_left, W_String) or isinstance(prim_right, W_String):
str_left = prim_left.ToString()
str_right = prim_right.ToString()
@@ -344,23 +355,22 @@
num_right = prim_right.ToNumber()
return W_Number(num_left + num_right)
-class Script(Node):
+class Script(Statement):
def __init__(self, nodes, var_decl, func_decl):
self.nodes = nodes
self.var_decl = var_decl
self.func_decl = func_decl
- def call(self, ctx):
+ def execute(self, ctx):
for var in self.var_decl:
ctx.variable.Put(var.name, w_Undefined)
for fun in self.func_decl:
- ctx.variable.Put(fun.name, fun.call(ctx))
-
-
+ ctx.variable.Put(fun.name, fun.eval(ctx))
+
try:
last = w_Undefined
for node in self.nodes:
- last = node.call(ctx)
+ last = node.execute(ctx)
return last
except ExecutionReturned, e:
return e.value
@@ -371,40 +381,40 @@
self.nodes.extend(newscript.nodes)
self.func_decl.extend(newscript.func_decl)
-class Semicolon(Node):
+class Semicolon(Statement):
def __init__(self, expr = None):
self.expr = expr
- def call(self, ctx):
+ def execute(self, ctx):
if self.expr is None:
return
- return self.expr.call(ctx)
+ return self.expr.execute(ctx)
-class String(Node):
+class String(Expression):
def __init__(self, strval):
self.strval = strval
- def call(self, ctx):
+ def eval(self, ctx):
return W_String(self.strval)
def get_literal(self):
return W_String(self.strval).ToString()
-class Return(Node):
+class Return(Statement):
def __init__(self, expr):
self.expr = expr
- def call(self, ctx):
- raise ExecutionReturned(self.expr.call(ctx))
+ def execute(self, ctx):
+ raise ExecutionReturned(self.expr.eval(ctx))
-class Throw(Node):
+class Throw(Statement):
def __init__(self, exception):
self.exception = exception
- def call(self, ctx):
- raise ThrowException(self.exception.call(ctx))
+ def execute(self, ctx):
+ raise ThrowException(self.exception.eval(ctx))
-class Try(Node):
+class Try(Statement):
# TODO: rewrite to use 'Undefined'
def __init__(self, tryblock, catchblock, finallyblock, catchparam):
self.tryblock = tryblock
@@ -412,21 +422,21 @@
self.finallyblock = finallyblock
self.catchparam = catchparam
- def call(self, ctx):
+ def execute(self, ctx):
e = None
try:
- tryresult = self.tryblock.call(ctx)
+ tryresult = self.tryblock.execute(ctx)
except ThrowException, excpt:
e = excpt
if self.catchblock is not None:
obj = W_Object()
obj.Put(self.catchparam, e.exception)
ctx.push_object(obj)
- tryresult = self.catchblock.call(ctx)
+ tryresult = self.catchblock.execute(ctx)
ctx.pop_object()
if self.finallyblock is not None:
- tryresult = self.finallyblock.call(ctx)
+ tryresult = self.finallyblock.execute(ctx)
#if there is no catchblock reraise the exception
if (e is not None) and (self.catchblock is None):
@@ -434,28 +444,28 @@
return tryresult
-class Undefined(Node):
- def call(self, ctx):
+class Undefined(Statement):
+ def execute(self, ctx):
return None
-class Vars(Node):
+class Vars(Statement):
def __init__(self, nodes):
self.nodes = nodes
- def call(self, ctx):
- print self.nodes
+ def execute(self, ctx):
+ #print self.nodes
for var in self.nodes:
- print var.name
- var.call(ctx)
+ #print var.name
+ var.execute(ctx)
-class While(Node):
+class While(Statement):
def __init__(self, condition, body):
self.condition = condition
self.body = body
- def call(self, ctx):
- while self.condition.call(ctx).ToBoolean():
- self.body.call(ctx)
+ def execute(self, ctx):
+ while self.condition.eval(ctx).ToBoolean():
+ self.body.execute(ctx)
def getlist(t):
item = gettreeitem(t, 'length')
@@ -470,7 +480,7 @@
if x.children[0].additional_info == name:
return x.children[1]
return
-
+
def from_tree(t):
if t is None:
return
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Mon Jan 8 18:10:57 2007
@@ -13,6 +13,8 @@
self.exception = exception
self.args = self.exception
+class JsTypeError(Exception):
+ pass
INFDEF = 1e300 * 1e300
NaN = INFDEF/INFDEF
@@ -41,7 +43,7 @@
def ToBoolean(self):
return False
- def ToPrimitive(self, hint=""):
+ def ToPrimitive(self, ctx, hint=""):
return self
def ToString(self):
@@ -63,7 +65,7 @@
class W_Primitive(W_Root):
"""unifying parent for primitives"""
- def ToPrimitive(self, PreferredType):
+ def ToPrimitive(self, ctx, PreferredType):
return self
class W_Object(W_Root):
@@ -81,8 +83,6 @@
return W_Object()
def Get(self, P):
- if not isinstance(P, str):
- P = P.ToString()
if P in self.propdict: return self.propdict[P].value
if self.Prototype is None: return w_Undefined
return self.Prototype.Get(P) # go down the prototype chain
@@ -93,11 +93,10 @@
return True
if self.Prototype is None: return True
return self.Prototype.CanPut(P)
-
+
def Put(self, P, V):
- if not isinstance(P, str):
- P = P.ToString()
- if not self.CanPut(P): return
+ if not self.CanPut(P):
+ return
if P in self.propdict:
self.propdict[P].value = V
else:
@@ -111,28 +110,28 @@
def Delete(P):
if P in self.propdict:
if self.propdict[P].DontDelete: return False
- self.propdict.pop(P)
+ del self.propdict[P]
return True
return True
-
- def DefaultValue(self, hint):
- def internal_def_value(tryone, trytwo):
- t1 = self.Get(tryone)
- if isinstance(t1, W_Object):
- val = t1.Call(this=self)
- if isinstance(val, W_Primitive):
- return val
- t2 = self.Get(trytwo)
- if isinstance(t2, W_Object):
- val = t2.Call(this=self)
- if isinstance(val, W_Primitive):
- return val
- raise jsTypeError
-
+
+ def internal_def_value(self, ctx, tryone, trytwo):
+ t1 = self.Get(tryone)
+ if isinstance(t1, W_Object):
+ val = t1.Call(ctx, this=self)
+ if isinstance(val, W_Primitive):
+ return val
+ t2 = self.Get(trytwo)
+ if isinstance(t2, W_Object):
+ val = t2.Call(ctx, this=self)
+ if isinstance(val, W_Primitive):
+ return val
+ raise JsTypeError
+
+ def DefaultValue(self, ctx, hint):
if hint == "String":
- internal_def_value("toString", "valueOf")
+ return self.internal_def_value(ctx, "toString", "valueOf")
else: #suppose hint is "Number" dunno what to do otherwise
- internal_def_value("valueOf", "toString")
+ return self.internal_def_value(ctx, "valueOf", "toString")
ToPrimitive = DefaultValue
@@ -140,27 +139,29 @@
return "[object %s]"%(self.Class,)
def __str__(self):
- return ""%(self.Class,
- self.propdict, self.Prototype)
+ return "" % self.Class
+
class W_Arguments(W_Object):
def __init__(self, callee, args):
W_Object.__init__(self)
self.Class = "arguments"
- self.propdict.pop("toString")
- self.propdict.pop("prototype")
+ del self.propdict["toString"]
+ del self.propdict["prototype"]
self.Put('callee', callee)
- self.Put('length', len(args))
- for i, arg in enumerate(args):
- self.Put(str(i), arg)
+ self.Put('length', W_Number(len(args)))
+## for i, arg in enumerate(args):
+## self.Put(str(i), arg)
+ for i in range(len(args)):
+ self.Put(str(i), args[i])
class ActivationObject(W_Object):
"""The object used on function calls to hold arguments and this"""
def __init__(self):
W_Object.__init__(self)
self.Class = "Activation"
- self.propdict.pop("toString")
- self.propdict.pop("prototype")
+ del self.propdict["toString"]
+ del self.propdict["prototype"]
class W_FunctionObject(W_Object):
def __init__(self, function, ctx):
@@ -172,22 +173,24 @@
self.scope = ctx.scope[:]
def Call(self, ctx, args=[], this=None):
- print "* start of function call"
- print " args = ", args
+ #print "* start of function call"
+ #print " args = ", args
act = ActivationObject()
- for i, arg in enumerate(self.function.params):
+ #for i, arg in enumerate(self.function.params):
+ for i in range(len(self.function.params)):
+ arg = self.function.params[i]
try:
value = args[i]
except IndexError:
value = w_Undefined
act.Put(self.function.params[i], value)
act.Put('this', this)
- print " act.propdict = ", act.propdict
+ #print " act.propdict = ", act.propdict
w_Arguments = W_Arguments(self, args)
act.Put('arguments', w_Arguments)
newctx = function_context(self.scope, act, this)
- val = self.function.body.call(ctx=newctx)
- print "* end of function call return = ", val
+ val = self.function.body.execute(ctx=newctx)
+ #print "* end of function call return = ", val
return val
class W_Array(W_Object):
@@ -262,7 +265,7 @@
class W_Number(W_Primitive):
def __init__(self, floatval):
- print "w_number = ", floatval
+ #print "w_number = ", floatval
self.floatval = floatval
def ToString(self):
@@ -289,8 +292,9 @@
#W_Object.__init__(self)
self.builtinfunction = builtinfunction
- def Call(self, context, args=[], this = None):
- return self.builtinfunction(*args)
+ def Call(self, ctx, args=[], this = None):
+ assert len(args) == 0
+ return W_String(self.builtinfunction()) # ???
class W_List(W_Root):
def __init__(self, list_w):
@@ -338,9 +342,9 @@
def resolve_identifier(self, identifier):
for obj in self.scope:
if obj.HasProperty(identifier):
- return Reference(identifier, obj)
+ return W_Reference(identifier, obj)
- return Reference(identifier)
+ return W_Reference(identifier)
def global_context(w_global):
@@ -370,7 +374,7 @@
ctx.property = Property('', w_Undefined)
return ctx
-class Reference(object):
+class W_Reference(W_Root):
"""Reference Type"""
def __init__(self, property_name, base=None):
self.base = base
@@ -396,4 +400,4 @@
def __str__(self):
return "< " + str(self.base) + " -> " + str(self.property_name) + " >"
-
\ No newline at end of file
+
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Mon Jan 8 18:10:57 2007
@@ -18,11 +18,11 @@
class TestInterp(object):
def test_simple(self):
- assert Plus(Number(3), Number(4)).call(ExecutionContext()).floatval == 7
+ assert Plus(Number(3), Number(4)).eval(ExecutionContext()).floatval == 7
l = []
interpreter.writer = l.append
Script([Semicolon(Call(Identifier('print', None),
- List([Number(1), Number(2)])))],[],[]).call(ExecutionContext())
+ List([Number(1), Number(2)])))],[],[]).execute(ExecutionContext())
assert l == ['1,2']
def assert_prints(self, code, assval):
From arigo at codespeak.net Mon Jan 8 18:25:26 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 18:25:26 +0100 (CET)
Subject: [pypy-svn] r36303 -
pypy/branch/jit-codegen-refactor/pypy/translator/tool
Message-ID: <20070108172526.8F4C71007D@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 18:25:23 2007
New Revision: 36303
Modified:
pypy/branch/jit-codegen-refactor/pypy/translator/tool/reftracker.py
Log:
Make reftracker robust against missing attributes.
Modified: pypy/branch/jit-codegen-refactor/pypy/translator/tool/reftracker.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/translator/tool/reftracker.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/translator/tool/reftracker.py Mon Jan 8 18:25:23 2007
@@ -117,8 +117,13 @@
for key, value in basetype.__dict__.items():
if (type(value) is MemberDescriptorType or
type(value) is AttributeType):
- if value.__get__(o1) is o2:
- slst.append(str(key))
+ try:
+ o1value = value.__get__(o1)
+ except:
+ pass
+ else:
+ if o1value is o2:
+ slst.append(str(key))
return ', '.join(slst)
From arigo at codespeak.net Mon Jan 8 18:33:05 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 18:33:05 +0100 (CET)
Subject: [pypy-svn] r36304 - in pypy/branch/jit-codegen-refactor/pypy/jit:
codegen/llgraph timeshifter
Message-ID: <20070108173305.83E4910075@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 18:33:00 2007
New Revision: 36304
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py
Log:
(mwh, arigo)
Updates to make the promotion tests work with the new changes.
Fix an old obscure**42 problem that was always there, but not
found because show_incremental_progress() didn't call checkgraph().
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/llimpl.py Mon Jan 8 18:33:00 2007
@@ -6,7 +6,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rtupletype
from pypy.objspace.flow import model as flowmodel
-from pypy.translator.simplify import eliminate_empty_blocks, join_blocks
+from pypy.translator.simplify import eliminate_empty_blocks
from pypy.translator.unsimplify import varoftype
from pypy.rpython.module.support import init_opaque_object
from pypy.rpython.module.support import to_opaque_object, from_opaque_object
@@ -350,28 +350,28 @@
graph = _getgraph(gv_func)
_closelink(link, [returnvar], graph.prereturnblock)
-def closelinktofreshblock(link, inputargs=None):
+def closelinktofreshblock(link, inputargs=None, otherlink=None):
link = from_opaque_object(link)
- vars = link.prevblock.getvariables()
- if inputargs is not None:
- existing_vars = dict.fromkeys(vars)
- vars = _inputvars(inputargs)
- for v in vars:
- assert v in existing_vars
- nextblock = flowmodel.Block(list(vars))
- link.args = vars
- link.target = nextblock
- return to_opaque_object(nextblock)
-
-def closelinktofreshblockwithsameargsasotherlink(link, otherlink):
- link = from_opaque_object(link)
- otherlink = from_opaque_object(otherlink)
- existing_vars = dict.fromkeys(link.prevblock.getvariables())
- vars = list(otherlink.args)
- for v in vars:
+ prevblockvars = link.prevblock.getvariables()
+ # the next block's inputargs come from 'inputargs' if specified
+ if inputargs is None:
+ inputvars = prevblockvars
+ else:
+ inputvars = _inputvars(inputargs)
+ # the link's arguments are the same as the inputvars, except
+ # if otherlink is specified, in which case they are copied from otherlink
+ if otherlink is None:
+ linkvars = list(inputvars)
+ else:
+ otherlink = from_opaque_object(otherlink)
+ linkvars = list(otherlink.args)
+ # check linkvars for consistency
+ existing_vars = dict.fromkeys(prevblockvars)
+ for v in linkvars:
assert v in existing_vars
- nextblock = flowmodel.Block(list(vars))
- link.args = vars
+
+ nextblock = flowmodel.Block(inputvars)
+ link.args = linkvars
link.target = nextblock
return to_opaque_object(nextblock)
@@ -398,29 +398,29 @@
self.type_system = LowLevelTypeSystem.instance
def fixduplicatevars(graph):
- incomingvars = {} # {block: {var_from_link_args: True}}
- for link in graph.iterlinks():
- vars = incomingvars.setdefault(link.target, {})
- for v in link.args:
- if isinstance(v, flowmodel.Variable):
- vars[v] = True
- for block, vars in incomingvars.items():
- for v in block.inputargs:
- if v in vars:
- # this block needs renaming of all its input variables
- mapping = {}
- for a in block.inputargs:
- mapping[a] = a1 = flowmodel.Variable(a)
- a1.concretetype = a.concretetype
- block.renamevariables(mapping)
- break
+ # just rename all vars in all blocks
+ try:
+ done = graph._llimpl_blocks_already_renamed
+ except AttributeError:
+ done = graph._llimpl_blocks_already_renamed = {}
+
+ for block in graph.iterblocks():
+ if block not in done:
+ mapping = {}
+ for a in block.inputargs:
+ mapping[a] = a1 = flowmodel.Variable(a)
+ a1.concretetype = a.concretetype
+ block.renamevariables(mapping)
+ done[block] = True
def _buildgraph(graph):
# rgenop makes graphs that use the same variable in several blocks,
fixduplicatevars(graph) # fix this now
flowmodel.checkgraph(graph)
eliminate_empty_blocks(graph)
- join_blocks(graph)
+ # we cannot call join_blocks(graph) here! It has a subtle problem:
+ # it copies operations between blocks without renaming op.result.
+ # See test_promotion.test_many_promotions for a failure.
graph.rgenop = True
return graph
@@ -441,8 +441,10 @@
def show_incremental_progress(gv_func):
from pypy import conftest
+ graph = _getgraph(gv_func)
+ fixduplicatevars(graph)
+ flowmodel.checkgraph(graph)
if conftest.option.view:
- graph = _getgraph(gv_func)
eliminate_empty_blocks(graph)
graph.show()
@@ -532,7 +534,6 @@
setannotation(closelink, None)
setannotation(closereturnlink, None)
setannotation(closelinktofreshblock, s_Block)
-setannotation(closelinktofreshblockwithsameargsasotherlink, s_Block)
setannotation(isptrtype, annmodel.SomeBool())
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 18:33:00 2007
@@ -47,22 +47,22 @@
class LLFlexSwitch(CodeGenSwitch):
- def __init__(self, b, g):
+ def __init__(self, b, g, args_gv):
self.b = b
self.gv_f = g
self.cases_gv = []
+ self.args_gv = args_gv
def add_case(self, gv_case):
self.cases_gv.append(gv_case) # not used so far, but keeps ptrs alive
l_case = llimpl.add_case(self.b, gv_case.v)
- b = llimpl.closelinktofreshblockwithsameargsasotherlink(l_case,
- self.l_default)
+ b = llimpl.closelinktofreshblock(l_case, self.args_gv, self.l_default)
return LLBuilder(self.gv_f, b)
- def _add_default(self, args_gv):
+ def _add_default(self):
l_default = llimpl.add_default(self.b)
self.l_default = l_default
- b = llimpl.closelinktofreshblock(l_default, args_gv)
+ b = llimpl.closelinktofreshblock(l_default, self.args_gv, None)
return LLBuilder(self.gv_f, b)
class LLBuilder(GenBuilder):
@@ -176,8 +176,8 @@
self._close()
def _jump(self, l_jump, l_no_jump, args_for_jump_gv):
- self.b = llimpl.closelinktofreshblock(l_no_jump, None)
- b2 = llimpl.closelinktofreshblock(l_jump, args_for_jump_gv)
+ self.b = llimpl.closelinktofreshblock(l_no_jump, None, None)
+ b2 = llimpl.closelinktofreshblock(l_jump, args_for_jump_gv, None)
later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
later_builder.later_block = b2
later_builder.jumped_from = self
@@ -193,9 +193,9 @@
def flexswitch(self, gv_switchvar, args_gv):
llimpl.closeblockswitch(self.b, gv_switchvar.v)
- flexswitch = LLFlexSwitch(self.b, self.gv_f)
+ flexswitch = LLFlexSwitch(self.b, self.gv_f, args_gv)
self._close()
- return (flexswitch, flexswitch._add_default(args_gv))
+ return (flexswitch, flexswitch._add_default())
def _close(self):
self.b = llimpl.nullblock
@@ -210,7 +210,7 @@
def pause_writing(self, args_gv):
lnk = llimpl.closeblock1(self.b)
- b2 = llimpl.closelinktofreshblock(lnk, args_gv)
+ b2 = llimpl.closelinktofreshblock(lnk, args_gv, None)
self._close()
later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
later_builder.later_block = b2
@@ -282,7 +282,7 @@
constPrebuiltGlobal = genconst
def replay(self, label, kinds):
- builder = LLBuilder(label.g)
+ builder = LLBuilder(label.g, llimpl.nullblock)
args_gv = builder._newblock(kinds)
return builder, args_gv
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/timeshifter/rtimeshift.py Mon Jan 8 18:33:00 2007
@@ -628,14 +628,12 @@
jitstate.enter_block(incoming, memo)
switchblock = enter_next_block(jitstate, incoming)
gv_switchvar = promotebox.genvar
- flexswitch = builder.flexswitch(gv_switchvar)
-
+ incoming_gv = [box.genvar for box in incoming]
+ flexswitch, default_builder = builder.flexswitch(gv_switchvar,
+ incoming_gv)
if jitstate.resuming is None:
- incoming_gv = [box.genvar for box in incoming]
- default_builder = flexswitch.add_default()
jitstate.curbuilder = default_builder
# default case of the switch:
- enter_block(jitstate)
pm = PromotionPoint(flexswitch, incoming_gv,
jitstate.promotion_path)
#debug_print(lltype.Void, "PROMOTE")
@@ -683,8 +681,6 @@
newbuilder = flexswitch.add_case(promotenode.gv_value)
jitstate.curbuilder = newbuilder
-
- enter_block(jitstate)
return False
# ____________________________________________________________
From arigo at codespeak.net Mon Jan 8 19:10:42 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 19:10:42 +0100 (CET)
Subject: [pypy-svn] r36306 - in
pypy/branch/jit-codegen-refactor/pypy/jit/codegen: i386 llvm ppc
Message-ID: <20070108181042.1A3EA10071@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 19:10:38 2007
New Revision: 36306
Modified:
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/i386/conftest.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llvm/conftest.py
pypy/branch/jit-codegen-refactor/pypy/jit/codegen/ppc/conftest.py
Log:
Skip these tests, to be able to merge the branch.
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/i386/conftest.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/i386/conftest.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/i386/conftest.py Mon Jan 8 19:10:38 2007
@@ -5,6 +5,7 @@
class Directory(py.test.collect.Directory):
def run(self):
+ import py; py.test.skip("in-progress")
try:
processor = detect_cpu.autodetect()
except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llvm/conftest.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llvm/conftest.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/llvm/conftest.py Mon Jan 8 19:10:38 2007
@@ -3,9 +3,10 @@
#XXX Should check here if llvm supports a JIT for this platform (perhaps using lli?)
-#class Directory(py.test.collect.Directory):
-#
-# def run(self):
+class Directory(py.test.collect.Directory):
+
+ def run(self):
+ py.test.skip("in-progress")
# try:
# processor = detect_cpu.autodetect()
# except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/branch/jit-codegen-refactor/pypy/jit/codegen/ppc/conftest.py
==============================================================================
--- pypy/branch/jit-codegen-refactor/pypy/jit/codegen/ppc/conftest.py (original)
+++ pypy/branch/jit-codegen-refactor/pypy/jit/codegen/ppc/conftest.py Mon Jan 8 19:10:38 2007
@@ -5,6 +5,7 @@
class Directory(py.test.collect.Directory):
def run(self):
+ import py; py.test.skip("in-progress")
try:
processor = detect_cpu.autodetect()
except detect_cpu.ProcessorAutodetectError, e:
From arigo at codespeak.net Mon Jan 8 19:16:41 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 19:16:41 +0100 (CET)
Subject: [pypy-svn] r36308 - in pypy/dist/pypy: jit/codegen jit/codegen/i386
jit/codegen/llgraph jit/codegen/llgraph/test jit/codegen/llvm
jit/codegen/ppc jit/timeshifter translator/tool
Message-ID: <20070108181641.D8DD410076@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 19:16:38 2007
New Revision: 36308
Modified:
pypy/dist/pypy/jit/codegen/i386/conftest.py
pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/llvm/conftest.py
pypy/dist/pypy/jit/codegen/model.py
pypy/dist/pypy/jit/codegen/ppc/conftest.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/transform.py
pypy/dist/pypy/translator/tool/reftracker.py
Log:
(mwh, arigo)
svn merge -r36236:36306 http://codespeak.net/svn/pypy/branch/jit-codegen-refactor/pypy
Refactor a bit the codegen interface of the JIT, using
enter_next_block() less often. This should make register allocation
easier.
Fix an old obscure**42 problem that was always there, but not
found because show_incremental_progress() didn't call checkgraph().
Make reftracker robust against missing attributes.
Skip the real backend tests, to be able to merge the branch.
Modified: pypy/dist/pypy/jit/codegen/i386/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/conftest.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/conftest.py Mon Jan 8 19:16:38 2007
@@ -5,6 +5,7 @@
class Directory(py.test.collect.Directory):
def run(self):
+ import py; py.test.skip("in-progress")
try:
processor = detect_cpu.autodetect()
except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Mon Jan 8 19:16:38 2007
@@ -6,7 +6,7 @@
from pypy.rpython.lltypesystem import lltype, llmemory, rtupletype
from pypy.objspace.flow import model as flowmodel
-from pypy.translator.simplify import eliminate_empty_blocks, join_blocks
+from pypy.translator.simplify import eliminate_empty_blocks
from pypy.translator.unsimplify import varoftype
from pypy.rpython.module.support import init_opaque_object
from pypy.rpython.module.support import to_opaque_object, from_opaque_object
@@ -350,6 +350,31 @@
graph = _getgraph(gv_func)
_closelink(link, [returnvar], graph.prereturnblock)
+def closelinktofreshblock(link, inputargs=None, otherlink=None):
+ link = from_opaque_object(link)
+ prevblockvars = link.prevblock.getvariables()
+ # the next block's inputargs come from 'inputargs' if specified
+ if inputargs is None:
+ inputvars = prevblockvars
+ else:
+ inputvars = _inputvars(inputargs)
+ # the link's arguments are the same as the inputvars, except
+ # if otherlink is specified, in which case they are copied from otherlink
+ if otherlink is None:
+ linkvars = list(inputvars)
+ else:
+ otherlink = from_opaque_object(otherlink)
+ linkvars = list(otherlink.args)
+ # check linkvars for consistency
+ existing_vars = dict.fromkeys(prevblockvars)
+ for v in linkvars:
+ assert v in existing_vars
+
+ nextblock = flowmodel.Block(inputvars)
+ link.args = linkvars
+ link.target = nextblock
+ return to_opaque_object(nextblock)
+
def casting_link(source, sourcevars, target):
assert len(sourcevars) == len(target.inputargs)
linkargs = []
@@ -372,10 +397,30 @@
from pypy.rpython.typesystem import LowLevelTypeSystem
self.type_system = LowLevelTypeSystem.instance
+def fixduplicatevars(graph):
+ # just rename all vars in all blocks
+ try:
+ done = graph._llimpl_blocks_already_renamed
+ except AttributeError:
+ done = graph._llimpl_blocks_already_renamed = {}
+
+ for block in graph.iterblocks():
+ if block not in done:
+ mapping = {}
+ for a in block.inputargs:
+ mapping[a] = a1 = flowmodel.Variable(a)
+ a1.concretetype = a.concretetype
+ block.renamevariables(mapping)
+ done[block] = True
+
def _buildgraph(graph):
+ # rgenop makes graphs that use the same variable in several blocks,
+ fixduplicatevars(graph) # fix this now
flowmodel.checkgraph(graph)
eliminate_empty_blocks(graph)
- join_blocks(graph)
+ # we cannot call join_blocks(graph) here! It has a subtle problem:
+ # it copies operations between blocks without renaming op.result.
+ # See test_promotion.test_many_promotions for a failure.
graph.rgenop = True
return graph
@@ -396,8 +441,10 @@
def show_incremental_progress(gv_func):
from pypy import conftest
+ graph = _getgraph(gv_func)
+ fixduplicatevars(graph)
+ flowmodel.checkgraph(graph)
if conftest.option.view:
- graph = _getgraph(gv_func)
eliminate_empty_blocks(graph)
graph.show()
@@ -486,6 +533,7 @@
setannotation(add_default, s_Link)
setannotation(closelink, None)
setannotation(closereturnlink, None)
+setannotation(closelinktofreshblock, s_Block)
setannotation(isptrtype, annmodel.SomeBool())
Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py Mon Jan 8 19:16:38 2007
@@ -47,30 +47,31 @@
class LLFlexSwitch(CodeGenSwitch):
- def __init__(self, b, g):
+ def __init__(self, b, g, args_gv):
self.b = b
self.gv_f = g
self.cases_gv = []
+ self.args_gv = args_gv
def add_case(self, gv_case):
self.cases_gv.append(gv_case) # not used so far, but keeps ptrs alive
l_case = llimpl.add_case(self.b, gv_case.v)
- builder = LLBuilder(self.gv_f)
- builder.lnk = l_case
- return builder
+ b = llimpl.closelinktofreshblock(l_case, self.args_gv, self.l_default)
+ return LLBuilder(self.gv_f, b)
- def add_default(self):
+ def _add_default(self):
l_default = llimpl.add_default(self.b)
- builder = LLBuilder(self.gv_f)
- builder.lnk = l_default
- return builder
+ self.l_default = l_default
+ b = llimpl.closelinktofreshblock(l_default, self.args_gv, None)
+ return LLBuilder(self.gv_f, b)
class LLBuilder(GenBuilder):
- lnk = llimpl.nulllink
+ jumped_from = None
- def __init__(self, g):
+ def __init__(self, g, block):
self.rgenop = rgenop
self.gv_f = g
+ self.b = block
def end(self):
llimpl.end(self.gv_f)
@@ -156,8 +157,7 @@
return [LLVar(llimpl.geninputarg(newb, kind.v)) for kind in kinds]
def enter_next_block(self, kinds, args_gv):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
newb_args_gv = self._newblock(kinds)
llimpl.closelink(lnk, args_gv, self.b)
for i in range(len(args_gv)):
@@ -165,38 +165,56 @@
return LLLabel(self.b, self.gv_f)
def finish_and_goto(self, args_gv, target):
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
llimpl.closelink(lnk, args_gv, target.b)
+ self._close()
def finish_and_return(self, sigtoken, gv_returnvar):
gv_returnvar = gv_returnvar or gv_dummy_placeholder
- lnk = self.lnk or llimpl.closeblock1(self.b)
- self.lnk = llimpl.nulllink
+ lnk = llimpl.closeblock1(self.b)
llimpl.closereturnlink(lnk, gv_returnvar.v, self.gv_f)
+ self._close()
- def jump_if_true(self, gv_cond):
- l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.nullblock
- later_builder = LLBuilder(self.gv_f)
- later_builder.lnk = l_true
- self.lnk = l_false
+ def _jump(self, l_jump, l_no_jump, args_for_jump_gv):
+ self.b = llimpl.closelinktofreshblock(l_no_jump, None, None)
+ b2 = llimpl.closelinktofreshblock(l_jump, args_for_jump_gv, None)
+ later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
+ later_builder.later_block = b2
+ later_builder.jumped_from = self
return later_builder
- def jump_if_false(self, gv_cond):
+ def jump_if_true(self, gv_cond, args_for_jump_gv):
l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
- self.b = llimpl.nullblock
- later_builder = LLBuilder(self.gv_f)
- later_builder.lnk = l_false
- self.lnk = l_true
- return later_builder
+ return self._jump(l_true, l_false, args_for_jump_gv)
- def flexswitch(self, gv_switchvar):
+ def jump_if_false(self, gv_cond, args_for_jump_gv):
+ l_false, l_true = llimpl.closeblock2(self.b, gv_cond.v)
+ return self._jump(l_false, l_true, args_for_jump_gv)
+
+ def flexswitch(self, gv_switchvar, args_gv):
llimpl.closeblockswitch(self.b, gv_switchvar.v)
- flexswitch = LLFlexSwitch(self.b, self.gv_f)
+ flexswitch = LLFlexSwitch(self.b, self.gv_f, args_gv)
+ self._close()
+ return (flexswitch, flexswitch._add_default())
+
+ def _close(self):
self.b = llimpl.nullblock
- self.lnk = llimpl.nulllink
- return flexswitch
+
+ def start_writing(self):
+ assert self.b == llimpl.nullblock
+ if self.jumped_from:
+ assert self.jumped_from.b == llimpl.nullblock
+ assert self.later_block != llimpl.nullblock
+ self.b = self.later_block
+ self.later_block = llimpl.nullblock
+
+ def pause_writing(self, args_gv):
+ lnk = llimpl.closeblock1(self.b)
+ b2 = llimpl.closelinktofreshblock(lnk, args_gv, None)
+ self._close()
+ later_builder = LLBuilder(self.gv_f, llimpl.nullblock)
+ later_builder.later_block = b2
+ return later_builder
def show_incremental_progress(self):
llimpl.show_incremental_progress(self.gv_f)
@@ -208,8 +226,7 @@
def newgraph(self, (ARGS_gv, gv_RESULT, gv_FUNCTYPE), name):
gv_func = llimpl.newgraph(gv_FUNCTYPE.v, name)
- builder = LLBuilder(gv_func)
- builder.b = llimpl.getstartblock(gv_func)
+ builder = LLBuilder(gv_func, llimpl.getstartblock(gv_func))
inputargs_gv = [LLVar(llimpl.getinputarg(builder.b, i))
for i in range(len(ARGS_gv))]
return builder, LLConst(gv_func), inputargs_gv
@@ -265,7 +282,7 @@
constPrebuiltGlobal = genconst
def replay(self, label, kinds):
- builder = LLBuilder(label.g)
+ builder = LLBuilder(label.g, llimpl.nullblock)
args_gv = builder._newblock(kinds)
return builder, args_gv
Modified: pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py Mon Jan 8 19:16:38 2007
@@ -67,8 +67,9 @@
const0 = rgenop.genconst(0)
gv1 = builder.genop2('int_lt', gv0, const0)
- false_builder = builder.jump_if_false(gv1)
+ false_builder = builder.jump_if_false(gv1, [gv0])
builder.finish_and_return(f1_token, const0)
+ false_builder.start_writing()
false_builder.finish_and_return(f1_token, gv0)
builder.end()
if_ptr = gv_if.revealconst(lltype.Ptr(F1))
@@ -110,8 +111,9 @@
gv_result1 = builder.genop2('int_mul', gv_result0, gv_i0)
gv_i1 = builder.genop2('int_add', gv_i0, const1)
gv2 = builder.genop2('int_le', gv_i1, gv1)
- loop_builder = builder.jump_if_true(gv2)
+ loop_builder = builder.jump_if_true(gv2, [gv_result1, gv_i1, gv1])
builder.finish_and_return(f1_token, gv_result1)
+ loop_builder.start_writing()
loop_builder.finish_and_goto([gv_result1, gv_i1, gv1], loopblock)
builder.end()
@@ -167,31 +169,21 @@
"""
builder, gv_switch, (gv0, gv1) = rgenop.newgraph(f2_token, "switch")
- flexswitch = builder.flexswitch(gv0)
+ flexswitch, default_builder = builder.flexswitch(gv0, [gv1])
const21 = rgenop.genconst(21)
# case == 0
const0 = rgenop.genconst(0)
case_builder = flexswitch.add_case(const0)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case0] = case_args_gv
- gv_res_case0 = case_builder.genop2('int_mul', const21, gv1_case0)
+ gv_res_case0 = case_builder.genop2('int_mul', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case0)
# case == 1
const1 = rgenop.genconst(1)
case_builder = flexswitch.add_case(const1)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case1] = case_args_gv
- gv_res_case1 = case_builder.genop2('int_add', const21, gv1_case1)
+ gv_res_case1 = case_builder.genop2('int_add', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case1)
# default
- default_builder = flexswitch.add_default()
- default_args_gv = [gv1]
- default_builder.enter_next_block([signed_tok], default_args_gv)
- [gv1_default] = default_args_gv
- default_builder.finish_and_return(f2_token, gv1_default)
+ default_builder.finish_and_return(f2_token, gv1)
builder.end()
switch_ptr = gv_switch.revealconst(lltype.Ptr(F2))
Modified: pypy/dist/pypy/jit/codegen/llvm/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/conftest.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/conftest.py Mon Jan 8 19:16:38 2007
@@ -3,9 +3,10 @@
#XXX Should check here if llvm supports a JIT for this platform (perhaps using lli?)
-#class Directory(py.test.collect.Directory):
-#
-# def run(self):
+class Directory(py.test.collect.Directory):
+
+ def run(self):
+ py.test.skip("in-progress")
# try:
# processor = detect_cpu.autodetect()
# except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/dist/pypy/jit/codegen/model.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/model.py (original)
+++ pypy/dist/pypy/jit/codegen/model.py Mon Jan 8 19:16:38 2007
@@ -86,22 +86,28 @@
zip(kinds, args_gv) gives the kindtoken and GenVarOrConst for
each inputarg of the block.
- The Obscure Bit: args_gv must be mutated in place to replace
- GenConsts with GenVars and optionally GenVars can be replaced
- with new GenVars, for example if the same value might live in
- different locations (registers, places on the stack) in
- different basic blocks.
+ The Obscure Bit: args_gv must be mutated in place until it is a
+ list of unique GenVars. So GenConsts must be replaced with
+ GenVars, and duplicate GenVars must be made unique. Optionally,
+ *all* GenVars can be replaced with new GenVars, for example if
+ the same value might live in different locations (registers,
+ places on the stack) in different basic blocks.
Returns an instance of GenLabel that can later be jumped to.
'''
- def jump_if_false(self, gv_condition):
+ def jump_if_false(self, gv_condition, args_for_jump_gv):
'''Make a fresh builder, insert in the current block a
check of gv_condition and a conditional jump to the new block
that is taken if gv_condition is false and return the new
- builder.'''
+ builder.
+
+ The current builder stays open. To make the backend\'s life
+ easier it must be closed before the fresh builder is used at
+ all, and the first thing to call on the latter is
+ start_writing().'''
- def jump_if_true(self, gv_condition):
+ def jump_if_true(self, gv_condition, args_for_jump_gv):
'''See above, with the obvious difference :)'''
def finish_and_return(self, sigtoken, gv_returnvar):
@@ -120,14 +126,20 @@
This "closes" the current builder.
'''
- def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch, args_gv):
'''The Fun Stuff.
Generates a switch on the value of gv_exitswitch that can have
cases added to it later, i.e. even after it\'s been executed a
few times.
- Returns an instance of CodeGenSwitch, see below.
+ args_gv is the list of live variables. It\'s the list of
+ variables that can be used in each switch case.
+
+ Returns a tuple:
+ - an instance of CodeGenSwitch (see below)
+ - a new builder for the default case, that will be jumped to
+ when the switched-on GenVar does not take the value of any case.
This "closes" the current builder.
'''
@@ -142,14 +154,17 @@
'''Optional method: prints or logs the position of the generated code
along with the given msg.
'''
- def pause(self):
+ def pause_writing(self, args_gv):
'''Optional method: Called when the builder will not be used for a
- while. This allows the builder to free temporary resources needed
- during code generation. The next call to the builder will have to be
- to enter_next_block, finish_and_got, finish_and_return or resume.
+ while. This allows the builder to be freed. The pause_writing()
+ method returns the next builder, on which you will have to call
+ start_writing() before you continue.
'''
- def resume(self):
- 'Resumes a paused builder.'
+ return self
+
+ def start_writing(self):
+ '''Start a builder returned by jump_if_xxx(), or resumes a paused
+ builder.'''
class GenLabel(object):
'''A "smart" label. Represents an address of the start of a basic
@@ -258,8 +273,3 @@
def add_case(self, gv_case):
'''Make a new builder that will be jumped to when the
switched-on GenVar takes the value of the GenConst gv_case.'''
-
- def add_default(self):
- '''Make a new builder that will be jumped to when the
- switched-on GenVar does not take the value of any case.'''
-
Modified: pypy/dist/pypy/jit/codegen/ppc/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/conftest.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/conftest.py Mon Jan 8 19:16:38 2007
@@ -5,6 +5,7 @@
class Directory(py.test.collect.Directory):
def run(self):
+ import py; py.test.skip("in-progress")
try:
processor = detect_cpu.autodetect()
except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Mon Jan 8 19:16:38 2007
@@ -308,18 +308,12 @@
resuming.mergesleft -= 1
def guard_global_merge(jitstate, resumepoint):
- jitstate.curbuilder.pause()
+ jitstate.pause()
dispatchqueue = jitstate.frame.dispatchqueue
jitstate.next = dispatchqueue.global_merge_chain
dispatchqueue.global_merge_chain = jitstate
jitstate.resumepoint = resumepoint
-def enter_block(jitstate):
- incoming = []
- memo = rvalue.enter_block_memo()
- jitstate.enter_block(incoming, memo)
- enter_next_block(jitstate, incoming)
-
def split(jitstate, switchredbox, resumepoint, *greens_gv):
exitgvar = switchredbox.getgenvar(jitstate.curbuilder)
if exitgvar.is_const:
@@ -330,7 +324,8 @@
node = resuming.path.pop()
assert isinstance(node, PromotionPathSplit)
return node.answer
- later_builder = jitstate.curbuilder.jump_if_false(exitgvar)
+ locals_gv = jitstate.get_locals_gv()
+ later_builder = jitstate.curbuilder.jump_if_false(exitgvar, locals_gv)
jitstate2 = jitstate.split(later_builder, resumepoint, list(greens_gv))
if resuming is None:
node = jitstate.promotion_path
@@ -339,6 +334,8 @@
return True
def collect_split(jitstate_chain, resumepoint, *greens_gv):
+ # assumes that the head of the jitstate_chain is ready for writing,
+ # and all the other jitstates in the chain are paused
greens_gv = list(greens_gv)
pending = jitstate_chain
resuming = jitstate_chain.resuming
@@ -388,12 +385,12 @@
if dispatchqueue.split_chain is not None:
jitstate = dispatchqueue.split_chain
dispatchqueue.split_chain = jitstate.next
- enter_block(jitstate)
+ jitstate.curbuilder.start_writing()
return jitstate
elif dispatchqueue.global_merge_chain is not None:
jitstate = dispatchqueue.global_merge_chain
dispatchqueue.global_merge_chain = jitstate.next
- jitstate.curbuilder.resume()
+ jitstate.curbuilder.start_writing()
return jitstate
else:
oldjitstate.resumepoint = -1
@@ -441,7 +438,7 @@
def save_return(jitstate):
# add 'jitstate' to the chain of return-jitstates
- jitstate.curbuilder.pause()
+ jitstate.pause()
dispatchqueue = jitstate.frame.dispatchqueue
jitstate.next = dispatchqueue.return_chain
dispatchqueue.return_chain = jitstate
@@ -631,14 +628,12 @@
jitstate.enter_block(incoming, memo)
switchblock = enter_next_block(jitstate, incoming)
gv_switchvar = promotebox.genvar
- flexswitch = builder.flexswitch(gv_switchvar)
-
+ incoming_gv = [box.genvar for box in incoming]
+ flexswitch, default_builder = builder.flexswitch(gv_switchvar,
+ incoming_gv)
if jitstate.resuming is None:
- incoming_gv = [box.genvar for box in incoming]
- default_builder = flexswitch.add_default()
jitstate.curbuilder = default_builder
# default case of the switch:
- enter_block(jitstate)
pm = PromotionPoint(flexswitch, incoming_gv,
jitstate.promotion_path)
#debug_print(lltype.Void, "PROMOTE")
@@ -686,8 +681,6 @@
newbuilder = flexswitch.add_case(promotenode.gv_value)
jitstate.curbuilder = newbuilder
-
- enter_block(jitstate)
return False
# ____________________________________________________________
@@ -864,6 +857,19 @@
self.exc_type_box = self.exc_type_box .replace(memo)
self.exc_value_box = self.exc_value_box.replace(memo)
+ def get_locals_gv(self):
+ # get all the genvars that are "alive", i.e. stored in the JITState
+ # or the VirtualFrames
+ incoming = []
+ memo = rvalue.enter_block_memo()
+ self.enter_block(incoming, memo)
+ locals_gv = [redbox.genvar for redbox in incoming]
+ return locals_gv
+
+ def pause(self):
+ locals_gv = self.get_locals_gv()
+ self.curbuilder = self.curbuilder.pause_writing(locals_gv)
+
def residual_ll_exception(self, ll_evalue):
ll_etype = ll_evalue.typeptr
@@ -916,13 +922,13 @@
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
- jitstate.curbuilder.resume()
+ jitstate.curbuilder.start_writing()
res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
return_marker,
force_merge=force_merge)
if res is False: # not finished
if still_pending:
- still_pending.curbuilder.pause()
+ still_pending.pause()
jitstate.next = still_pending
still_pending = jitstate
@@ -932,16 +938,19 @@
if return_chain is not None:
return_cache = {}
still_pending = None
+ was_paused = False
while return_chain is not None:
jitstate = return_chain
return_chain = return_chain.next
- jitstate.curbuilder.resume()
+ if was_paused:
+ jitstate.curbuilder.start_writing()
+ was_paused = True # only the head of the list was *not* paused
res = retrieve_jitstate_for_merge(return_cache, jitstate, (),
return_marker,
force_merge=force_merge)
if res is False: # not finished
if still_pending:
- still_pending.curbuilder.pause()
+ still_pending.pause()
jitstate.next = still_pending
still_pending = jitstate
return still_pending
@@ -1000,4 +1009,7 @@
while jitstate is not None:
leave_frame(jitstate)
jitstate = jitstate.next
- return return_chain # a jitstate, which is the head of the chain
+ # return the jitstate which is the head of the chain,
+ # ready for further writing
+ return_chain.curbuilder.start_writing()
+ return return_chain
Modified: pypy/dist/pypy/jit/timeshifter/transform.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/transform.py (original)
+++ pypy/dist/pypy/jit/timeshifter/transform.py Mon Jan 8 19:16:38 2007
@@ -290,19 +290,19 @@
resulttype = lltype.Bool)
block.exitswitch = v_flag
- true_block = Block([])
- true_link = Link([], true_block)
- true_link.exitcase = True
- true_link.llexitcase = True
- block.recloseblock(link_f, true_link)
-
- reds, greens = self.sort_by_color(link_t.args)
- self.genop(true_block, 'save_locals', reds)
- self.genop(true_block, 'enter_block', [])
- true_block.closeblock(Link(link_t.args, link_t.target))
+## true_block = Block([])
+## true_link = Link([], true_block)
+## true_link.exitcase = True
+## true_link.llexitcase = True
+## block.recloseblock(link_f, true_link)
+
+## reds, greens = self.sort_by_color(link_t.args)
+## self.genop(true_block, 'save_locals', reds)
+## self.genop(true_block, 'enter_block', [])
+## true_block.closeblock(Link(link_t.args, link_t.target))
- SSA_to_SSI({block : True, # reachable from outside
- true_block: False}, self.hannotator)
+## SSA_to_SSI({block : True, # reachable from outside
+## true_block: False}, self.hannotator)
def get_resume_point_link(self, block):
try:
@@ -433,6 +433,7 @@
if self.graphcolor == 'gray':
self.genop(block, 'save_locals', [])
elif self.graphcolor == 'yellow':
+ self.genop(block, 'save_locals', [])
self.genop(block, 'save_greens', [v_retbox])
elif self.graphcolor == 'red':
self.genop(block, 'save_locals', [v_retbox])
Modified: pypy/dist/pypy/translator/tool/reftracker.py
==============================================================================
--- pypy/dist/pypy/translator/tool/reftracker.py (original)
+++ pypy/dist/pypy/translator/tool/reftracker.py Mon Jan 8 19:16:38 2007
@@ -117,8 +117,13 @@
for key, value in basetype.__dict__.items():
if (type(value) is MemberDescriptorType or
type(value) is AttributeType):
- if value.__get__(o1) is o2:
- slst.append(str(key))
+ try:
+ o1value = value.__get__(o1)
+ except:
+ pass
+ else:
+ if o1value is o2:
+ slst.append(str(key))
return ', '.join(slst)
From arigo at codespeak.net Mon Jan 8 19:16:56 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Mon, 8 Jan 2007 19:16:56 +0100 (CET)
Subject: [pypy-svn] r36309 - pypy/branch/jit-codegen-refactor
Message-ID: <20070108181656.1EB7A1007D@code0.codespeak.net>
Author: arigo
Date: Mon Jan 8 19:16:54 2007
New Revision: 36309
Removed:
pypy/branch/jit-codegen-refactor/
Log:
Branch merged.
From antocuni at codespeak.net Mon Jan 8 19:30:11 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 8 Jan 2007 19:30:11 +0100 (CET)
Subject: [pypy-svn] r36310 - pypy/dist/pypy/lang/js
Message-ID: <20070108183011.1302C10076@code0.codespeak.net>
Author: antocuni
Date: Mon Jan 8 19:30:10 2007
New Revision: 36310
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsparser.py
Log:
More steps in making js rpythonic.
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Mon Jan 8 19:30:10 2007
@@ -1,5 +1,5 @@
-from pypy.lang.js.jsparser import parse
+from pypy.lang.js.jsparser import parse, parse_bytecode
from pypy.lang.js.jsobj import *
from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal
@@ -62,6 +62,10 @@
newscript = from_tree(temp_tree)
self.script.append_script(newscript)
+ def load_bytecode(self, bytecode):
+ temp_tree = parse_bytecode(bytecode)
+ self.script = from_tree(temp_tree)
+
def run(self):
"""run the interpreter"""
return self.script.execute(self.global_context)
@@ -486,7 +490,7 @@
return
tp = gettreeitem(t, 'type').additional_info
if tp == 'ARRAY_INIT':
- return Array(getlist(d))
+ return Array(getlist(t))
elif tp == 'ASSIGN':
return Assign(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'BLOCK':
Modified: pypy/dist/pypy/lang/js/jsparser.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsparser.py (original)
+++ pypy/dist/pypy/lang/js/jsparser.py Mon Jan 8 19:30:10 2007
@@ -41,14 +41,19 @@
read_code = read_js_output(code_string)
output = read_code.split(os.linesep)
#print '\n'.join(output)
- t = parse_bytecode(output)
- unquote(t)
+ t = parse_bytecode("\n".join(output))
#print "-----------------\n",t
#print "-----------------\n",t.children[0].children[0].additional_info
return t
-
+
def parse_bytecode(bytecode):
- regexs, rules, ToAST = parse_ebnf("""
+ t = parse_tree(bytecode)
+ #print "0000000",t
+ tree = ToAST().transform(t)
+ unquote(tree)
+ return tree
+
+regexs, rules, ToAST = parse_ebnf("""
QUOTED_STRING: "'[^\\']*'";
IGNORE: " |\n";
data: | | ;
@@ -56,8 +61,4 @@
dictentry: QUOTED_STRING [":"] data;
list: ["["] (data [","])* data ["]"];
""")
- parse = make_parse_function(regexs, rules, eof=True)
- t = parse("\n".join(bytecode))
- #print "0000000",t
- return ToAST().transform(t)
-
+parse_tree = make_parse_function(regexs, rules, eof=True)
From antocuni at codespeak.net Mon Jan 8 19:31:08 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 8 Jan 2007 19:31:08 +0100 (CET)
Subject: [pypy-svn] r36311 - pypy/dist/pypy/translator/goal
Message-ID: <20070108183108.D05521007A@code0.codespeak.net>
Author: antocuni
Date: Mon Jan 8 19:31:05 2007
New Revision: 36311
Added:
pypy/dist/pypy/translator/goal/targetjsstandalone.py (contents, props changed)
Log:
First attempt to write a target for a standalone javascript interpreter.
Added: pypy/dist/pypy/translator/goal/targetjsstandalone.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/goal/targetjsstandalone.py Mon Jan 8 19:31:05 2007
@@ -0,0 +1,34 @@
+"""
+A simple standalone target for the javascript interpreter.
+"""
+
+import sys
+from pypy.rlib.streamio import open_file_as_stream
+from pypy.lang.js.interpreter import Interpreter
+from pypy.lang.js.interpreter import *
+from pypy.lang.js.jsobj import ExecutionReturned
+
+# __________ Entry point __________
+
+interp = Interpreter()
+
+def entry_point(argv):
+ if len(argv) == 2:
+ f = open_file_as_stream(argv[1])
+ interp.load_bytecode(f.readall())
+ interp.run()
+ return 0
+ elif argv[0] == 'foo':
+ raise ExecutionReturned(None)
+ else:
+ print "Usage: %s bytecodefile" % argv[0]
+ return 1
+
+# _____ Define and setup target ___
+
+def target(driver, args):
+ driver.exe_name = 'js-%(backend)s'
+ return entry_point, None
+
+if __name__ == '__main__':
+ entry_point(sys.argv)
From antocuni at codespeak.net Mon Jan 8 19:46:42 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Mon, 8 Jan 2007 19:46:42 +0100 (CET)
Subject: [pypy-svn] r36312 - pypy/dist/pypy/lang/js
Message-ID: <20070108184642.715621007E@code0.codespeak.net>
Author: antocuni
Date: Mon Jan 8 19:46:41 2007
New Revision: 36312
Modified:
pypy/dist/pypy/lang/js/interpreter.py
Log:
(antocuni, santagada)
more rpython
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Mon Jan 8 19:46:41 2007
@@ -203,13 +203,13 @@
s4 = s1.ToNumber()
s5 = s2.ToNumber()
if s4 == NaN or s5 == NaN:
- return None
+ return -1
if s4 < s5:
- return True
+ return 1
else:
- return False
+ return 0
else:
- pass
+ return -1
class Or(BinaryLogicOp):
def eval(self, ctx):
@@ -230,7 +230,7 @@
class Ge(BinaryComparisonOp):
def decision(self, ctx, op1, op2):
s5 = ARC(ctx, op1, op2)
- if s5 is None or s5:
+ if s5 in (-1, 1):
return W_Boolean(False)
else:
return W_Boolean(True)
@@ -238,7 +238,7 @@
class Gt(BinaryComparisonOp):
def decision(self, ctx, op1, op2):
s5 = ARC(ctx, op2, op1)
- if s5 is None:
+ if s5 == -1:
return W_Boolean(False)
else:
return W_Boolean(s5)
@@ -246,7 +246,7 @@
class Le(BinaryComparisonOp):
def decision(self, ctx, op1, op2):
s5 = ARC(ctx, op2, op1)
- if s5 is None or s5:
+ if s5 in (-1, 1):
return W_Boolean(False)
else:
return W_Boolean(True)
@@ -254,7 +254,7 @@
class Lt(BinaryComparisonOp):
def decision(self, ctx, op1, op2):
s5 = ARC(ctx, op1, op2)
- if s5 is None:
+ if s5 == -1:
return W_Boolean(False)
else:
return W_Boolean(s5)
@@ -279,7 +279,7 @@
class In(BinaryComparisonOp):
def decision(self, ctx, op1, op2):
if not isinstance(op2, W_Object):
- raise ThrowException("TypeError")
+ raise ThrowException(W_String("TypeError"))
name = op1.ToString()
return W_Boolean(op2.HasProperty(name))
From guido at codespeak.net Mon Jan 8 21:36:51 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Mon, 8 Jan 2007 21:36:51 +0100 (CET)
Subject: [pypy-svn] r36316 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070108203651.E7EB110064@code0.codespeak.net>
Author: guido
Date: Mon Jan 8 21:36:49 2007
New Revision: 36316
Added:
pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
Log:
File for managing who owes what in the food department (PyPy sprint Leysin
2007).
Added: pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
==============================================================================
--- (empty file)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt Mon Jan 8 21:36:49 2007
@@ -0,0 +1,16 @@
+Armin Rigo -10
+Anders Chrigstroem -10
+Samuele Pedroni -10
+Michael Hudson -10
+Niko Matsakis
+Antonio Cuni -10
+Maciej Fijalkowski -10
+Eric van Riet Paap
+Jacob Hallen -10
+Laura Creighton -10
+Holger Krekel -10
+Carl Friedrich Bolz -10
+Guido Wesdorp -10 +134
+Leonardo Santagada -10
+Alexandre Fayolle -10
+Sylvain Th?nault -10
From santagada at codespeak.net Mon Jan 8 22:04:06 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Mon, 8 Jan 2007 22:04:06 +0100 (CET)
Subject: [pypy-svn] r36317 - pypy/dist/pypy/lang/js
Message-ID: <20070108210406.F32B61006F@code0.codespeak.net>
Author: santagada
Date: Mon Jan 8 22:03:58 2007
New Revision: 36317
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
Log:
more rpython stuff
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Mon Jan 8 22:03:58 2007
@@ -72,11 +72,11 @@
class PropertyInit(Node):
def __init__(self, name, value):
- self.name = name
+ self.namein = name
self.value = value
def __repr__(self):
- return "<%s : %s>"%(str(self.name), str(self.value))
+ return "<%s : %s>"%(str(self.namein), str(self.value))
class Array(Expression):
@@ -340,7 +340,7 @@
w_obj = W_Object()
##print "properties = ", self.properties
for property in self.properties:
- name = property.name.get_literal()
+ name = property.namein.get_literal()
#print "prop name = ", name
w_expr = property.value.eval(ctx).GetValue()
w_obj.Put(name, w_expr)
@@ -428,6 +428,7 @@
def execute(self, ctx):
e = None
+ tryresult = w_Undefined
try:
tryresult = self.tryblock.execute(ctx)
except ThrowException, excpt:
@@ -508,8 +509,9 @@
elif tp == 'AND':
return And(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'FUNCTION':
- name = gettreeitem(t, 'name')
- if name is not None:
+ namesimb = gettreeitem(t, 'name')
+ name = None
+ if namesimb is not None:
name = name.additional_info
body = from_tree(gettreeitem(t, 'body'))
if gettreeitem(t, 'params').additional_info == '':
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Mon Jan 8 22:03:58 2007
@@ -55,11 +55,12 @@
def ToNumber(self):
return NaN
- def get_literal(self):
+ # def get_literal(self):
+ # return self.ToString()
+ #
+ def __str__(self):
return self.ToString()
-
- __str__ = get_literal
-
+
def __repr__(self):
return "<%s(%s)>" % (self.__class__.__name__, self.ToString())
@@ -199,8 +200,6 @@
self.Put('length', W_Number(0))
def Put(self, P, V):
- if not isinstance(P, str):
- P = P.ToString()
if not self.CanPut(P): return
if P in self.propdict:
self.propdict[P].value = V
From santagada at codespeak.net Tue Jan 9 11:24:39 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Tue, 9 Jan 2007 11:24:39 +0100 (CET)
Subject: [pypy-svn] r36323 - pypy/dist/pypy/lang/js
Message-ID: <20070109102439.BA32310068@code0.codespeak.net>
Author: santagada
Date: Tue Jan 9 11:24:38 2007
New Revision: 36323
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/jsparser.py
Log:
(antonio, santagada) finishing rpythonization
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Tue Jan 9 11:24:38 2007
@@ -484,11 +484,11 @@
for x in t.children:
if x.children[0].additional_info == name:
return x.children[1]
- return
+ return None
def from_tree(t):
if t is None:
- return
+ return None
tp = gettreeitem(t, 'type').additional_info
if tp == 'ARRAY_INIT':
return Array(getlist(t))
@@ -512,7 +512,7 @@
namesimb = gettreeitem(t, 'name')
name = None
if namesimb is not None:
- name = name.additional_info
+ name = namesimb.additional_info
body = from_tree(gettreeitem(t, 'body'))
if gettreeitem(t, 'params').additional_info == '':
params = []
@@ -569,9 +569,8 @@
elif tp == 'RETURN':
return Return(from_tree(gettreeitem(t, 'value')))
elif tp == 'SCRIPT':
- print "*funDecls:'' ", gettreeitem(t, 'funDecls') == ''
f = gettreeitem(t, 'funDecls')
- print f.symbol
+ # print f.symbol
if f.symbol == "dict":
func_decl = [from_tree(f),]
elif f.symbol == "list":
@@ -580,7 +579,7 @@
func_decl = []
v = gettreeitem(t, 'varDecls')
- print v.symbol
+ # print v.symbol
if v.symbol == "dict":
var_decl = [from_tree(v),]
elif v.symbol == "list":
@@ -590,7 +589,7 @@
return Script(getlist(t), var_decl, func_decl)
elif tp == 'SEMICOLON':
- if gettreeitem(t, 'expression') == 'null':
+ if gettreeitem(t, 'expression').additional_info == 'null':
return Semicolon()
return Semicolon(from_tree(gettreeitem(t, 'expression')))
elif tp == 'STRING':
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Tue Jan 9 11:24:38 2007
@@ -206,9 +206,11 @@
else:
try:
x = int(P)
- except: # FIXME: forgot the name of the exception
+ except ValueError:
x = -1
- if self.Get('length') < 0: pass
+ # FIXME: Get this working
+ # if x > self.Get('length'):
+ # self.propdict['length'].value = W_Number(x)
self.propdict[P] = Property(P, V)
class W_Undefined(W_Root):
Modified: pypy/dist/pypy/lang/js/jsparser.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsparser.py (original)
+++ pypy/dist/pypy/lang/js/jsparser.py Tue Jan 9 11:24:38 2007
@@ -40,15 +40,11 @@
def parse(code_string):
read_code = read_js_output(code_string)
output = read_code.split(os.linesep)
- #print '\n'.join(output)
t = parse_bytecode("\n".join(output))
- #print "-----------------\n",t
- #print "-----------------\n",t.children[0].children[0].additional_info
return t
def parse_bytecode(bytecode):
t = parse_tree(bytecode)
- #print "0000000",t
tree = ToAST().transform(t)
unquote(tree)
return tree
From arigo at codespeak.net Tue Jan 9 11:33:45 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 11:33:45 +0100 (CET)
Subject: [pypy-svn] r36325 - pypy/dist/pypy/annotation
Message-ID: <20070109103345.9E86110069@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 11:33:44 2007
New Revision: 36325
Modified:
pypy/dist/pypy/annotation/unaryop.py
Log:
A less confusing error message.
Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py (original)
+++ pypy/dist/pypy/annotation/unaryop.py Tue Jan 9 11:33:44 2007
@@ -641,7 +641,8 @@
args_s, kwds_s = args.unpack()
if kwds_s:
raise Exception("keyword arguments to call to a low-level fn ptr")
- llargs = [annotation_to_lltype(s_arg)._defl() for s_arg in args_s]
+ info = 'argument to ll function pointer call'
+ llargs = [annotation_to_lltype(s_arg,info)._defl() for s_arg in args_s]
v = p.ll_ptrtype._example()(*llargs)
return ll_to_annotation(v)
From ac at codespeak.net Tue Jan 9 11:33:50 2007
From: ac at codespeak.net (ac at codespeak.net)
Date: Tue, 9 Jan 2007 11:33:50 +0100 (CET)
Subject: [pypy-svn] r36326 - pypy/dist/lib-python
Message-ID: <20070109103350.D29B71007D@code0.codespeak.net>
Author: ac
Date: Tue Jan 9 11:33:49 2007
New Revision: 36326
Modified:
pypy/dist/lib-python/conftest.py
Log:
Workaround options problem.
Modified: pypy/dist/lib-python/conftest.py
==============================================================================
--- pypy/dist/lib-python/conftest.py (original)
+++ pypy/dist/lib-python/conftest.py Tue Jan 9 11:33:49 2007
@@ -301,15 +301,15 @@
self.core = core
def oldstyle(self):
- return self._oldstyle or pypy_option.oldstyle
+ return self._oldstyle #or pypy_option.oldstyle
oldstyle = property(oldstyle)
def usemodules(self):
- return self._usemodules + pypy_option.usemodules
+ return self._usemodules #+ pypy_option.usemodules
usemodules = property(usemodules)
def compiler(self):
- return self._compiler or pypy_option.compiler
+ return self._compiler #or pypy_option.compiler
compiler = property(compiler)
def getoptions(self):
From arigo at codespeak.net Tue Jan 9 11:34:17 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 11:34:17 +0100 (CET)
Subject: [pypy-svn] r36327 - in pypy/dist/pypy/annotation: . test
Message-ID: <20070109103417.741B61007F@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 11:34:11 2007
New Revision: 36327
Modified:
pypy/dist/pypy/annotation/builtin.py
pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
(mwh, arigo)
Avoid crashing with blocked blocks in an empty-range() situation.
Modified: pypy/dist/pypy/annotation/builtin.py
==============================================================================
--- pypy/dist/pypy/annotation/builtin.py (original)
+++ pypy/dist/pypy/annotation/builtin.py Tue Jan 9 11:34:11 2007
@@ -57,18 +57,27 @@
s_step = args[2]
else:
raise Exception, "range() takes 1 to 3 arguments"
+ empty = False # so far
if not s_step.is_constant():
step = 0 # this case signals a variable step
else:
step = s_step.const
if step == 0:
raise Exception, "range() with step zero"
- nonneg = False # so far
- if step > 0:
- nonneg = s_start.nonneg
- elif step < 0:
- nonneg = s_stop.nonneg or (s_stop.is_constant() and s_stop.const >= -1)
- return getbookkeeper().newlist(SomeInteger(nonneg=nonneg), range_step=step)
+ if s_start.is_constant() and s_stop.is_constant():
+ if len(range(s_start.const, s_stop.const, step)) == 0:
+ empty = True
+ if empty:
+ s_item = s_ImpossibleValue
+ else:
+ nonneg = False # so far
+ if step > 0:
+ nonneg = s_start.nonneg
+ elif step < 0:
+ nonneg = s_stop.nonneg or (s_stop.is_constant() and
+ s_stop.const >= -1)
+ s_item = SomeInteger(nonneg=nonneg)
+ return getbookkeeper().newlist(s_item, range_step=step)
builtin_xrange = builtin_range # xxx for now allow it
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Tue Jan 9 11:34:11 2007
@@ -2437,6 +2437,19 @@
s = a.build_types(fun, [float, float])
assert [s_item.knowntype for s_item in s.items] == [bool] * 6
+ def test_empty_range(self):
+ def g(lst):
+ total = 0
+ for i in range(len(lst)):
+ total += lst[i]
+ return total
+ def fun():
+ return g([])
+
+ a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
+ s = a.build_types(fun, [])
+ assert s.const == 0
+
def g(n):
return [0,1,2,n]
From arigo at codespeak.net Tue Jan 9 11:55:18 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 11:55:18 +0100 (CET)
Subject: [pypy-svn] r36328 - in pypy/dist/pypy/rpython: . ootypesystem test
Message-ID: <20070109105518.A15F610075@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 11:55:14 2007
New Revision: 36328
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/rlist.py
pypy/dist/pypy/rpython/rrange.py
pypy/dist/pypy/rpython/test/test_rrange.py
Log:
(mwh, arigo)
Make empty range()es rtype correctly.
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Tue Jan 9 11:55:14 2007
@@ -379,6 +379,10 @@
# 'ITEMTYPE_T' is used as a placeholder for indicating
# arguments that should have ITEMTYPE type. 'SELFTYPE_T' indicates 'self'
+ # XXX clean-up later! Rename _ITEMTYPE to ITEM. For now they are
+ # just synonyms, please use ITEM in new code.
+ self.ITEM = self._ITEMTYPE
+
generic_types = {
self.SELFTYPE_T: self,
self.ITEMTYPE_T: self._ITEMTYPE,
@@ -463,6 +467,11 @@
return self._KEYTYPE is not None and self._VALUETYPE is not None
def _init_methods(self):
+ # XXX clean-up later! Rename _KEYTYPE and _VALUETYPE to KEY and VALUE.
+ # For now they are just synonyms, please use KEY/VALUE in new code.
+ self.KEY = self._KEYTYPE
+ self.VALUE = self._VALUETYPE
+
self._generic_types = frozendict({
self.SELFTYPE_T: self,
self.KEYTYPE_T: self._KEYTYPE,
Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py (original)
+++ pypy/dist/pypy/rpython/rlist.py Tue Jan 9 11:55:14 2007
@@ -31,7 +31,8 @@
def rtyper_makerepr(self, rtyper):
listitem = self.listdef.listitem
s_value = listitem.s_value
- if listitem.range_step is not None and not listitem.mutated:
+ if (listitem.range_step is not None and not listitem.mutated and
+ not isinstance(s_value, annmodel.SomeImpossibleValue)):
return rtyper.type_system.rrange.RangeRepr(listitem.range_step)
elif (s_value.__class__ is annmodel.SomeObject and s_value.knowntype == object):
return robject.pyobj_repr
Modified: pypy/dist/pypy/rpython/rrange.py
==============================================================================
--- pypy/dist/pypy/rpython/rrange.py (original)
+++ pypy/dist/pypy/rpython/rrange.py Tue Jan 9 11:55:14 2007
@@ -118,11 +118,12 @@
raise ValueError
length = _ll_rangelen(start, stop, step)
l = LIST.ll_newlist(length)
- idx = 0
- while idx < length:
- l.ll_setitem_fast(idx, start)
- start += step
- idx += 1
+ if LIST.ITEM is not Void:
+ idx = 0
+ while idx < length:
+ l.ll_setitem_fast(idx, start)
+ start += step
+ idx += 1
return l
# ____________________________________________________________
Modified: pypy/dist/pypy/rpython/test/test_rrange.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rrange.py (original)
+++ pypy/dist/pypy/rpython/test/test_rrange.py Tue Jan 9 11:55:14 2007
@@ -124,6 +124,17 @@
res = self.interpret(fn, args)
assert res == intmask(fn(*args))
+ def test_empty_range(self):
+ def g(lst):
+ total = 0
+ for i in range(len(lst)):
+ total += lst[i]
+ return total
+ def fn():
+ return g([])
+ res = self.interpret(fn, [])
+ assert res == 0
+
class TestLLtype(BaseTestRrange, LLRtypeMixin):
from pypy.rpython.lltypesystem import rrange
From arigo at codespeak.net Tue Jan 9 11:58:09 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 11:58:09 +0100 (CET)
Subject: [pypy-svn] r36329 - in pypy/dist/pypy/jit/codegen: i386/test
llgraph/test test
Message-ID: <20070109105809.91FB910075@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 11:58:06 2007
New Revision: 36329
Added:
pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
Modified:
pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
(mwh, arigo)
Use the general rgenop_tests with the llgraph backend too.
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_rgenop.py Tue Jan 9 11:58:06 2007
@@ -3,3 +3,6 @@
class TestRI386Genop(AbstractRGenOpTests):
RGenOp = RI386GenOp
+
+ # for the individual tests see
+ # ====> ../../test/rgenop_tests.py
Added: pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py Tue Jan 9 11:58:06 2007
@@ -0,0 +1,25 @@
+import py
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.codegen.llgraph.rgenop import RGenOp
+from pypy.jit.codegen.llgraph.llimpl import testgengraph
+from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests
+from pypy.rpython.test.test_llinterp import interpret
+
+
+class TestLLGraphRGenop(AbstractRGenOpTests):
+ RGenOp = RGenOp
+
+ def cast(self, gv, nb_args):
+ F1 = lltype.FuncType([lltype.Signed] * nb_args, lltype.Signed)
+ ptr = gv.revealconst(lltype.Ptr(F1))
+ def runner(*args):
+ return testgengraph(ptr._obj.graph, list(args))
+ return runner
+
+ def getcompiled(self, runner, argtypes, annotatorpolicy):
+ def quasi_compiled_runner(*args):
+ return interpret(runner, args, policy=annotatorpolicy)
+ return quasi_compiled_runner
+
+ # for the individual tests see
+ # ====> ../../test/rgenop_tests.py
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Tue Jan 9 11:58:06 2007
@@ -67,7 +67,7 @@
builder, gv_branchingfn, [gv_x, gv_y] = rgenop.newgraph(sigtoken,
"branching")
gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(5))
- false_builder = builder.jump_if_false(gv_cond)
+ false_builder = builder.jump_if_false(gv_cond, [gv_y])
# true path
args_gv = [rgenop.genconst(1), gv_x, gv_y]
@@ -78,9 +78,7 @@
builder.finish_and_return(sigtoken, gv_s2)
# false path
- args_gv = [gv_y]
- false_builder.enter_next_block([signed_kind], args_gv)
- [gv_y] = args_gv
+ false_builder.start_writing()
false_builder.finish_and_return(sigtoken, gv_y)
# done
@@ -105,7 +103,7 @@
[gv_x, gv_y, gv_z] = args_gv
gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(0))
- bodybuilder = builder.jump_if_true(gv_cond)
+ bodybuilder = builder.jump_if_true(gv_cond, args_gv)
return args_gv, loopblock, bodybuilder
# loop exit
@@ -119,11 +117,7 @@
# loop body
def loop_body(rgenop, loopblock, bodybuilder, signed_kind, gv_x, gv_y, gv_z):
- args_gv = [gv_z, gv_y, gv_x]
- bodybuilder.enter_next_block(
- [signed_kind, signed_kind, signed_kind], args_gv)
- [gv_z, gv_y, gv_x] = args_gv
-
+ bodybuilder.start_writing()
gv_z2 = bodybuilder.genop2("int_mul", gv_x, gv_z)
gv_y2 = bodybuilder.genop2("int_add", gv_x, gv_y)
gv_x2 = bodybuilder.genop2("int_sub", gv_x, rgenop.genconst(1))
@@ -177,13 +171,9 @@
[gv_x1, gv_unused] = args_gv
gv_cond = builder.genop2("int_gt", gv_x1, rgenop.genconst(5))
- elsebuilder = builder.jump_if_false(gv_cond)
- elseargs_gv = [gv_x1]
+ elsebuilder = builder.jump_if_false(gv_cond, [gv_x1])
# 'then' block
- args_gv = [gv_x1]
- builder.enter_next_block([signed_kind], args_gv)
- [gv_x1] = args_gv
gv_x2 = builder.genop2("int_floordiv", gv_x1, rgenop.genconst(2))
# end block
@@ -194,9 +184,8 @@
builder.finish_and_return(sigtoken, gv_res)
# now the else branch
- elsebuilder.enter_next_block([signed_kind], elseargs_gv)
- [gv_x3] = elseargs_gv
- elsebuilder.finish_and_goto([gv_x3, gv_x3], label)
+ elsebuilder.start_writing()
+ elsebuilder.finish_and_goto([gv_x1, gv_x1], label)
# done
builder.end()
@@ -226,30 +215,20 @@
sigtoken = rgenop.sigToken(FUNC2)
builder, gv_switch, [gv0, gv1] = rgenop.newgraph(sigtoken, "switch")
- flexswitch = builder.flexswitch(gv0)
+ flexswitch, default_builder = builder.flexswitch(gv0, [gv1])
const21 = rgenop.genconst(21)
+ # default
+ default_builder.finish_and_return(sigtoken, gv1)
# case == 0
const0 = rgenop.genconst(0)
case_builder = flexswitch.add_case(const0)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_kind], case_args_gv)
- [gv1_case0] = case_args_gv
- gv_res_case0 = case_builder.genop2('int_mul', const21, gv1_case0)
+ gv_res_case0 = case_builder.genop2('int_mul', const21, gv1)
case_builder.finish_and_return(sigtoken, gv_res_case0)
- # default
- default_builder = flexswitch.add_default()
- default_args_gv = [gv1]
- default_builder.enter_next_block([signed_kind], default_args_gv)
- [gv1_default] = default_args_gv
- default_builder.finish_and_return(sigtoken, gv1_default)
# case == 1
const1 = rgenop.genconst(1)
case_builder = flexswitch.add_case(const1)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_kind], case_args_gv)
- [gv1_case1] = case_args_gv
- gv_res_case1 = case_builder.genop2('int_add', const21, gv1_case1)
+ gv_res_case1 = case_builder.genop2('int_add', const21, gv1)
case_builder.finish_and_return(sigtoken, gv_res_case1)
builder.end()
@@ -284,32 +263,22 @@
f2_token = rgenop.sigToken(FUNC2)
builder, gv_switch, (gv0, gv1) = rgenop.newgraph(f2_token, "large_switch")
- flexswitch = builder.flexswitch(gv0)
+ flexswitch, default_builder = builder.flexswitch(gv0, [gv1])
const21 = rgenop.genconst(21)
+ # default
+ default_builder.finish_and_return(f2_token, gv1)
# case == 0
const0 = rgenop.genconst(0)
case_builder = flexswitch.add_case(const0)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_case0] = case_args_gv
- gv_res_case0 = case_builder.genop2('int_mul', const21, gv1_case0)
+ gv_res_case0 = case_builder.genop2('int_mul', const21, gv1)
case_builder.finish_and_return(f2_token, gv_res_case0)
- # default
- default_builder = flexswitch.add_default()
- default_args_gv = [gv1]
- default_builder.enter_next_block([signed_tok], default_args_gv)
- [gv1_default] = default_args_gv
- default_builder.finish_and_return(f2_token, gv1_default)
# case == x
for x in range(1,11):
constx = rgenop.genconst(x)
case_builder = flexswitch.add_case(constx)
- case_args_gv = [gv1]
- case_builder.enter_next_block([signed_tok], case_args_gv)
- [gv1_casex] = case_args_gv
- const2px= rgenop.genconst(1<
Author: arigo
Date: Tue Jan 9 12:08:37 2007
New Revision: 36331
Modified:
pypy/dist/pypy/jit/codegen/i386/rgenop.py
Log:
(mwh, arigo)
Begin adapt i386/rgenop to the new interface.
Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/rgenop.py Tue Jan 9 12:08:37 2007
@@ -187,9 +187,12 @@
except CodeBlockOverflow:
self._reserve_more()
self._add_case(gv_case, targetbuilder)
+ targetbuilder._open()
return targetbuilder
def _add_case(self, gv_case, targetbuilder):
+ # XXX this code needs to be simplified, now that we always
+ # have a default case
start = self.nextfreepos
end = self.endfreepos
mc = self.rgenop.InMemoryCodeBuilder(start, end)
@@ -210,7 +213,7 @@
self._je_key = 0
self.nextfreepos = pos
- def add_default(self):
+ def _add_default(self):
rgenop = self.rgenop
targetbuilder = Builder._new_from_state(rgenop, self.saved_state)
self.default_case_builder = targetbuilder
@@ -218,6 +221,7 @@
end = self.endfreepos
mc = self.rgenop.InMemoryCodeBuilder(start, end)
self.default_case_key = targetbuilder.come_from(mc, 'JMP')
+ targetbuilder._open()
return targetbuilder
class Builder(GenBuilder):
@@ -268,18 +272,18 @@
mc.JMP(rel32(curpos))
mc.done()
- def pause(self):
- if self.mc is None:
- return
- start = self.mc.tell()
- self.mc.JMP(rel32(0))
- end = self.mc.tell()
- self.tail = (start, end)
- self.mc.done()
- self.rgenop.close_mc(self.mc)
- self.mc = None
+ def pause_writing(self, alive_vars_gv):
+ if self.mc is not None:
+ start = self.mc.tell()
+ self.mc.JMP(rel32(0))
+ end = self.mc.tell()
+ self.tail = (start, end)
+ self.mc.done()
+ self.rgenop.close_mc(self.mc)
+ self.mc = None
+ return self
- def resume(self):
+ def start_writing(self):
self._open()
def _emit_come_from(self, mc, insn, addr):
@@ -322,14 +326,14 @@
self.mc = None
def _fork(self):
- return self.rgenop.openbuilder(self.stackdepth)
+ return self.rgenop.newbuilder(self.stackdepth)
def _save_state(self):
return self.stackdepth
@staticmethod
def _new_from_state(rgenop, stackdepth):
- return rgenop.openbuilder(stackdepth)
+ return rgenop.newbuilder(stackdepth)
@specialize.arg(1)
def genop1(self, opname, gv_arg):
@@ -493,13 +497,13 @@
seen[gv.stackpos] = None
return Label(self.mc.tell(), arg_positions, self.stackdepth)
- def jump_if_false(self, gv_condition):
+ def jump_if_false(self, gv_condition, args_gv):
targetbuilder = self._fork()
self.mc.CMP(gv_condition.operand(self), imm8(0))
targetbuilder.come_from(self.mc, 'JE')
return targetbuilder
- def jump_if_true(self, gv_condition):
+ def jump_if_true(self, gv_condition, args_gv):
targetbuilder = self._fork()
self.mc.CMP(gv_condition.operand(self), imm8(0))
targetbuilder.come_from(self.mc, 'JNE')
@@ -519,11 +523,11 @@
self.mc.JMP(rel32(target.startaddr))
self._close()
- def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch, args_gv):
result = FlexSwitch(self.rgenop)
result.initialize(self, gv_exitswitch)
self._close()
- return result
+ return result, result._add_default()
def show_incremental_progress(self):
pass
@@ -1006,11 +1010,11 @@
def check_no_open_mc(self):
assert len(self.mcs) == self.total_code_blocks
- def openbuilder(self, stackdepth):
+ def newbuilder(self, stackdepth):
return Builder(self, stackdepth)
def newgraph(self, sigtoken, name):
- builder = self.openbuilder(self._initial_stack_depth(sigtoken))
+ builder = self.newbuilder(self._initial_stack_depth(sigtoken))
builder._open() # Force builder to have an mc
entrypoint = builder.mc.tell()
inputargs_gv = builder._write_prologue(sigtoken)
From ac at codespeak.net Tue Jan 9 12:08:44 2007
From: ac at codespeak.net (ac at codespeak.net)
Date: Tue, 9 Jan 2007 12:08:44 +0100 (CET)
Subject: [pypy-svn] r36332 - in pypy/dist/pypy/interpreter: pyparser
pyparser/test stablecompiler test
Message-ID: <20070109110844.9D5BB1007D@code0.codespeak.net>
Author: ac
Date: Tue Jan 9 12:08:43 2007
New Revision: 36332
Modified:
pypy/dist/pypy/interpreter/pyparser/astbuilder.py
pypy/dist/pypy/interpreter/pyparser/ebnfparse.py
pypy/dist/pypy/interpreter/pyparser/pysymbol.py
pypy/dist/pypy/interpreter/pyparser/pythonparse.py
pypy/dist/pypy/interpreter/pyparser/symbol.py
pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
pypy/dist/pypy/interpreter/stablecompiler/transformer.py
pypy/dist/pypy/interpreter/test/test_syntax.py
Log:
Stick to Python 2.4 syntax!
Modified: pypy/dist/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/astbuilder.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/astbuilder.py Tue Jan 9 12:08:43 2007
@@ -778,13 +778,18 @@
def build_test(builder, nb):
atoms = get_atoms(builder, nb)
- if len(atoms) == 1:
+ l = len(atoms)
+ if l == 1:
builder.push(atoms[0])
- elif len(atoms) == 5:
+ elif l == 5 and atoms[1].get_value() == 'if':
builder.push(
ast.CondExpr(atoms[2], atoms[0], atoms[4], atoms[1].lineno))
else:
- assert False, "invalid number of atoms for rule 'test'"
+ lineno = atoms[1].lineno
+ items = []
+ for i in range(0,l,2): # this is atoms not 1
+ items.append(atoms[i])
+ builder.push(ast.Or(items, lineno))
# Note: we do not include a build_old_test() because it does not need to do
# anything.
@@ -1542,7 +1547,7 @@
# Build two almost identical ASTRULES dictionaries
ASTRULES = dict([(sym[key], value) for (key, value) in
- ASTRULES_Template.iteritems()])
+ ASTRULES_Template.iteritems() if key in sym])
del ASTRULES_Template
## Stack elements definitions ###################################
Modified: pypy/dist/pypy/interpreter/pyparser/ebnfparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/ebnfparse.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/ebnfparse.py Tue Jan 9 12:08:43 2007
@@ -261,7 +261,7 @@
from pprint import pprint
if __name__ == "__main__":
- grambuild = parse_grammar(file('data/Grammar2.5a'))
+ grambuild = parse_grammar(file('data/Grammar2.4'))
for i,r in enumerate(grambuild.items):
print "% 3d : %s" % (i, r)
pprint(grambuild.terminals.keys())
Modified: pypy/dist/pypy/interpreter/pyparser/pysymbol.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pysymbol.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/pysymbol.py Tue Jan 9 12:08:43 2007
@@ -45,6 +45,10 @@
"""NOT RPYTHON"""
assert type(sym)==str
return self.sym_values[ sym ]
+
+ def __contains__(self, sym):
+ """NOT RPYTHON"""
+ return sym in self.sym_values
_cpython_symbols = SymbolMapper( symbol.sym_name )
Modified: pypy/dist/pypy/interpreter/pyparser/pythonparse.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/pythonparse.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/pythonparse.py Tue Jan 9 12:08:43 2007
@@ -132,7 +132,7 @@
# unfortunately the command line options are not parsed yet, so it cannot
# be made configurable yet
-PYTHON_GRAMMAR, PYPY_VERSION = get_grammar_file("2.5a")
+PYTHON_GRAMMAR, PYPY_VERSION = get_grammar_file("2.4")
def python_grammar(fname):
"""returns a PythonParser build from the specified grammar file"""
Modified: pypy/dist/pypy/interpreter/pyparser/symbol.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/symbol.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/symbol.py Tue Jan 9 12:08:43 2007
@@ -82,10 +82,6 @@
gen_if = 331
testlist1 = 332
encoding_decl = 333
-old_test = 334
-or_test = 335
-old_lambdef = 336
-with_stmt = 337
# Generate sym_name
Modified: pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py (original)
+++ pypy/dist/pypy/interpreter/pyparser/test/test_astbuilder.py Tue Jan 9 12:08:43 2007
@@ -210,8 +210,8 @@
# We do not export the following tests because we would have to implement 2.5
# features in the stable compiler (other than just building the AST).
expressions_inbetweenversions = expressions + [
- "1 if True else 2",
- "1 if False else 2",
+ #"1 if True else 2", # Disabled 2.5 syntax
+ #"1 if False else 2",
]
EXPECTED["k[v,]"] = ("Module(None, Stmt([Discard(Subscript(Name('k'), 2, "
@@ -794,7 +794,7 @@
]
def test_snippets():
- for snippet_name in SNIPPETS + NEW_GRAMMAR_SNIPPETS:
+ for snippet_name in SNIPPETS: # + NEW_GRAMMAR_SNIPPETS: # Disabled 2.5 syntax
filepath = os.path.join(os.path.dirname(__file__), 'samples', snippet_name)
source = file(filepath).read()
# To avoid using the stable compiler we pull an explicit AST out of the snippet
Modified: pypy/dist/pypy/interpreter/stablecompiler/transformer.py
==============================================================================
--- pypy/dist/pypy/interpreter/stablecompiler/transformer.py (original)
+++ pypy/dist/pypy/interpreter/stablecompiler/transformer.py Tue Jan 9 12:08:43 2007
@@ -616,10 +616,12 @@
else:
# Normal or-expression
return self.com_node(nodelist[0])
- else:
+ elif len(nodelist) == 5 and nodelist[1][0] =='if':
# Here we implement conditional expressions
return ast.CondExpr(nodelist[2], nodelist[0], nodelist[4],
nodelist[1].lineno)
+ else:
+ return self.com_binary(Or, nodelist)
def and_test(self, nodelist):
# not_test ('and' not_test)*
Modified: pypy/dist/pypy/interpreter/test/test_syntax.py
==============================================================================
--- pypy/dist/pypy/interpreter/test/test_syntax.py (original)
+++ pypy/dist/pypy/interpreter/test/test_syntax.py Tue Jan 9 12:08:43 2007
@@ -256,15 +256,24 @@
raise
-class AppTestCondExpr:
+class Py25AppTest:
+ def setup_class(self):
+ space = self.space
+ w_globals = space.newdict([])
+ space.exec_('import sys; not_25 = sys.version_info < (2,5)',
+ w_globals, w_globals)
+ not_25 = space.is_true(space.getitem(w_globals, space.wrap('not_25')))
+ if not_25:
+ py.test.skip('Needs python 2.5 grammar')
+class AppTestCondExpr(Py25AppTest):
def test_condexpr(self):
for s, expected in [("x = 1 if True else 2", 1),
("x = 1 if False else 2", 2)]:
exec s
assert x == expected
-class AppTestWith:
+class AppTestWith(Py25AppTest):
def test_with_simple(self):
s = """from __future__ import with_statement
From pedronis at codespeak.net Tue Jan 9 12:20:23 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 9 Jan 2007 12:20:23 +0100 (CET)
Subject: [pypy-svn] r36333 - pypy/dist/pypy/jit/timeshifter/test
Message-ID: <20070109112023.9F75A10078@code0.codespeak.net>
Author: pedronis
Date: Tue Jan 9 12:20:21 2007
New Revision: 36333
Modified:
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
another simple test already passing
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Tue Jan 9 12:20:21 2007
@@ -3,28 +3,29 @@
import py
+XY = lltype.GcForwardReference()
+GETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY)], lltype.Signed))
+SETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY), lltype.Signed],
+ lltype.Void))
+XY_ACCESS = lltype.Struct('xy',
+ ('get_x', GETTER),
+ ('set_x', SETTER),
+ ('get_y', GETTER),
+ ('set_y', SETTER),
+ hints = {'immutable': True},
+ )
+
+XY.become(lltype.GcStruct('xy',
+ ('access', lltype.Ptr(XY_ACCESS)),
+ ('x', lltype.Signed),
+ ('y', lltype.Signed),
+ hints = {'virtualizable': True}
+ ))
+
class TestVirtualizable(PortalTest):
def test_simple_explicit(self):
- XY = lltype.GcForwardReference()
- GETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY)], lltype.Signed))
- SETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY), lltype.Signed],
- lltype.Void))
- XY_ACCESS = lltype.Struct('xy',
- ('get_x', GETTER),
- ('set_x', SETTER),
- ('get_y', GETTER),
- ('set_y', SETTER),
- hints = {'immutable': True},
- )
-
- XY.become(lltype.GcStruct('xy',
- ('access', lltype.Ptr(XY_ACCESS)),
- ('x', lltype.Signed),
- ('y', lltype.Signed),
- hints = {'virtualizable': True}
- ))
-
+
def f(xy):
xy_access = xy.access
if xy_access:
@@ -52,3 +53,40 @@
assert len(residual_graph.startblock.inputargs) == 3
assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
[lltype.Ptr(XY), lltype.Signed, lltype.Signed])
+
+ def test_simple_explicit_set(self):
+
+ def f(xy):
+ xy_access = xy.access
+ if xy_access:
+ x = xy_access.get_x(xy)
+ else:
+ x = xy.x
+ xy_access = xy.access
+ if xy_access:
+ xy_access.set_y(xy, 1)
+ else:
+ xy.y = 1
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ return x+y
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ return f(xy)
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 21
+ self.check_insns(getfield=0, setfield=0)
+ residual_graph = self.get_residual_graph()
+ assert len(residual_graph.startblock.inputargs) == 3
+ assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
+ [lltype.Ptr(XY), lltype.Signed, lltype.Signed])
+
+
From santagada at codespeak.net Tue Jan 9 12:26:55 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Tue, 9 Jan 2007 12:26:55 +0100 (CET)
Subject: [pypy-svn] r36335 - pypy/dist/pypy/lang/js
Message-ID: <20070109112655.396F810078@code0.codespeak.net>
Author: santagada
Date: Tue Jan 9 12:26:38 2007
New Revision: 36335
Modified:
pypy/dist/pypy/lang/js/interpreter.py
Log:
actually passing the tests now
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Tue Jan 9 12:26:38 2007
@@ -589,9 +589,10 @@
return Script(getlist(t), var_decl, func_decl)
elif tp == 'SEMICOLON':
- if gettreeitem(t, 'expression').additional_info == 'null':
+ expr = gettreeitem(t, 'expression')
+ if isinstance(expr, Symbol):
return Semicolon()
- return Semicolon(from_tree(gettreeitem(t, 'expression')))
+ return Semicolon(from_tree(expr))
elif tp == 'STRING':
return String(gettreeitem(t, 'value').additional_info)
elif tp == 'THIS':
From antocuni at codespeak.net Tue Jan 9 13:11:24 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 9 Jan 2007 13:11:24 +0100 (CET)
Subject: [pypy-svn] r36341 - in pypy/dist/pypy/translator/backendopt: . test
Message-ID: <20070109121124.6AA8B10069@code0.codespeak.net>
Author: antocuni
Date: Tue Jan 9 13:11:19 2007
New Revision: 36341
Modified:
pypy/dist/pypy/translator/backendopt/all.py
pypy/dist/pypy/translator/backendopt/malloc.py
pypy/dist/pypy/translator/backendopt/test/test_all.py
pypy/dist/pypy/translator/backendopt/test/test_malloc.py
Log:
Re-revert to revision 36067, and fix what caused test_all to fail.
Things learned: never guess whether type_system should contain
'lltype' or 'lltypesystem'... :-(
Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py (original)
+++ pypy/dist/pypy/translator/backendopt/all.py Tue Jan 9 13:11:19 2007
@@ -92,6 +92,7 @@
def inline_malloc_removal_phase(config, translator, graphs, inline_threshold,
call_count_pred=None):
+ type_system = translator.rtyper.type_system.name
log.inlining("phase with threshold factor: %s" % inline_threshold)
# inline functions in each other
@@ -113,7 +114,7 @@
if config.mallocs:
tot = 0
for graph in graphs:
- count = remove_simple_mallocs(graph)
+ count = remove_simple_mallocs(graph, type_system)
if count:
# remove typical leftovers from malloc removal
removenoops.remove_same_as(graph)
Modified: pypy/dist/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/malloc.py Tue Jan 9 13:11:19 2007
@@ -2,6 +2,7 @@
from pypy.objspace.flow.model import SpaceOperation, traverse
from pypy.tool.algo.unionfind import UnionFind
from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.ootypesystem import ootype
from pypy.translator.simplify import remove_identical_vars
from pypy.translator.backendopt.support import log
@@ -49,7 +50,58 @@
raise NotImplementedError
def flowin(self, block, count, var, newvarsmap):
- raise NotImplementedError
+ # in this 'block', follow where the 'var' goes to and replace
+ # it by a flattened-out family of variables. This family is given
+ # by newvarsmap, whose keys are the 'flatnames'.
+ vars = {var: True}
+ self.last_removed_access = None
+
+ def list_newvars():
+ return [newvarsmap[key] for key in self.flatnames]
+
+ assert block.operations != ()
+ self.newops = []
+ for op in block.operations:
+ for arg in op.args[1:]: # should be the first arg only
+ assert arg not in vars
+ if op.args and op.args[0] in vars:
+ self.flowin_op(op, vars, newvarsmap)
+ elif op.result in vars:
+ assert op.opname == self.MALLOC_OP
+ assert vars == {var: True}
+ progress = True
+ # drop the "malloc" operation
+ newvarsmap = self.flatconstants.copy() # zero initial values
+ # if there are substructures, they are now individually
+ # malloc'ed in an exploded way. (They will typically be
+ # removed again by the next malloc removal pass.)
+ for key in self.needsubmallocs:
+ v = Variable()
+ v.concretetype = self.newvarstype[key]
+ c = Constant(v.concretetype.TO, lltype.Void)
+ if c.value == op.args[0].value:
+ progress = False # replacing a malloc with
+ # the same malloc!
+ newop = SpaceOperation(self.MALLOC_OP, [c], v)
+ self.newops.append(newop)
+ newvarsmap[key] = v
+ count[0] += progress
+ else:
+ self.newops.append(op)
+
+ assert block.exitswitch not in vars
+
+ for link in block.exits:
+ newargs = []
+ for arg in link.args:
+ if arg in vars:
+ newargs += list_newvars()
+ else:
+ newargs.append(arg)
+ link.args[:] = newargs
+
+ self.insert_keepalives(list_newvars())
+ block.operations[:] = self.newops
def compute_lifetimes(self, graph):
"""Compute the static data flow of the graph: returns a list of LifeTime
@@ -367,144 +419,173 @@
pass
return S, fldname
- def flowin(self, block, count, var, newvarsmap):
- # in this 'block', follow where the 'var' goes to and replace
- # it by a flattened-out family of variables. This family is given
- # by newvarsmap, whose keys are the 'flatnames'.
- vars = {var: True}
- last_removed_access = None
-
- def list_newvars():
- return [newvarsmap[key] for key in self.flatnames]
-
- assert block.operations != ()
- newops = []
- for op in block.operations:
- for arg in op.args[1:]: # should be the first arg only
- assert arg not in vars
- if op.args and op.args[0] in vars:
- if op.opname in ("getfield", "getarrayitem"):
- S = op.args[0].concretetype.TO
- fldname = op.args[1].value
- key = self.key_for_field_access(S, fldname)
- if key in self.accessed_substructs:
- c_name = Constant('data', lltype.Void)
- newop = SpaceOperation("getfield",
- [newvarsmap[key], c_name],
- op.result)
- else:
- newop = SpaceOperation("same_as",
- [newvarsmap[key]],
- op.result)
- newops.append(newop)
- last_removed_access = len(newops)
- elif op.opname in ("setfield", "setarrayitem"):
- S = op.args[0].concretetype.TO
- fldname = op.args[1].value
- key = self.key_for_field_access(S, fldname)
- assert key in newvarsmap
- if key in self.accessed_substructs:
- c_name = Constant('data', lltype.Void)
- newop = SpaceOperation("setfield",
- [newvarsmap[key], c_name, op.args[2]],
- op.result)
- newops.append(newop)
- else:
- newvarsmap[key] = op.args[2]
- last_removed_access = len(newops)
- elif op.opname in ("same_as", "cast_pointer"):
- assert op.result not in vars
- vars[op.result] = True
- # Consider the two pointers (input and result) as
- # equivalent. We can, and indeed must, use the same
- # flattened list of variables for both, as a "setfield"
- # via one pointer must be reflected in the other.
- elif op.opname == 'keepalive':
- last_removed_access = len(newops)
- elif op.opname in ("getsubstruct", "getarraysubstruct",
- "direct_fieldptr"):
- S = op.args[0].concretetype.TO
- fldname = op.args[1].value
- if op.opname == "getarraysubstruct":
- fldname = 'item%d' % fldname
- equiv = self.equivalent_substruct(S, fldname)
- if equiv:
- # exactly like a cast_pointer
- assert op.result not in vars
- vars[op.result] = True
- else:
- # do it with a getsubstruct on the independently
- # malloc'ed GcStruct
- if op.opname == "direct_fieldptr":
- opname = "direct_fieldptr"
- else:
- opname = "getsubstruct"
- v = newvarsmap[S, fldname]
- cname = Constant('data', lltype.Void)
- newop = SpaceOperation(opname,
- [v, cname],
- op.result)
- newops.append(newop)
- elif op.opname in ("ptr_iszero", "ptr_nonzero"):
- # we know the pointer is not NULL if it comes from
- # a successful malloc
- c = Constant(op.opname == "ptr_nonzero", lltype.Bool)
- newop = SpaceOperation('same_as', [c], op.result)
- newops.append(newop)
- else:
- raise AssertionError, op.opname
- elif op.result in vars:
- assert op.opname == self.MALLOC_OP
- assert vars == {var: True}
- progress = True
- # drop the "malloc" operation
- newvarsmap = self.flatconstants.copy() # zero initial values
- # if there are substructures, they are now individually
- # malloc'ed in an exploded way. (They will typically be
- # removed again by the next malloc removal pass.)
- for key in self.needsubmallocs:
- v = Variable()
- v.concretetype = self.newvarstype[key]
- c = Constant(v.concretetype.TO, lltype.Void)
- if c.value == op.args[0].value:
- progress = False # replacing a malloc with
- # the same malloc!
- newop = SpaceOperation(self.MALLOC_OP, [c], v)
- newops.append(newop)
- newvarsmap[key] = v
- count[0] += progress
+ def flowin_op(self, op, vars, newvarsmap):
+ if op.opname in ("getfield", "getarrayitem"):
+ S = op.args[0].concretetype.TO
+ fldname = op.args[1].value
+ key = self.key_for_field_access(S, fldname)
+ if key in self.accessed_substructs:
+ c_name = Constant('data', lltype.Void)
+ newop = SpaceOperation("getfield",
+ [newvarsmap[key], c_name],
+ op.result)
else:
- newops.append(op)
-
- assert block.exitswitch not in vars
-
- for link in block.exits:
- newargs = []
- for arg in link.args:
- if arg in vars:
- newargs += list_newvars()
+ newop = SpaceOperation("same_as",
+ [newvarsmap[key]],
+ op.result)
+ self.newops.append(newop)
+ self.last_removed_access = len(self.newops)
+ elif op.opname in ("setfield", "setarrayitem"):
+ S = op.args[0].concretetype.TO
+ fldname = op.args[1].value
+ key = self.key_for_field_access(S, fldname)
+ assert key in newvarsmap
+ if key in self.accessed_substructs:
+ c_name = Constant('data', lltype.Void)
+ newop = SpaceOperation("setfield",
+ [newvarsmap[key], c_name, op.args[2]],
+ op.result)
+ self.newops.append(newop)
+ else:
+ newvarsmap[key] = op.args[2]
+ self.last_removed_access = len(self.newops)
+ elif op.opname in ("same_as", "cast_pointer"):
+ assert op.result not in vars
+ vars[op.result] = True
+ # Consider the two pointers (input and result) as
+ # equivalent. We can, and indeed must, use the same
+ # flattened list of variables for both, as a "setfield"
+ # via one pointer must be reflected in the other.
+ elif op.opname == 'keepalive':
+ self.last_removed_access = len(self.newops)
+ elif op.opname in ("getsubstruct", "getarraysubstruct",
+ "direct_fieldptr"):
+ S = op.args[0].concretetype.TO
+ fldname = op.args[1].value
+ if op.opname == "getarraysubstruct":
+ fldname = 'item%d' % fldname
+ equiv = self.equivalent_substruct(S, fldname)
+ if equiv:
+ # exactly like a cast_pointer
+ assert op.result not in vars
+ vars[op.result] = True
+ else:
+ # do it with a getsubstruct on the independently
+ # malloc'ed GcStruct
+ if op.opname == "direct_fieldptr":
+ opname = "direct_fieldptr"
else:
- newargs.append(arg)
- link.args[:] = newargs
-
- if last_removed_access is not None:
+ opname = "getsubstruct"
+ v = newvarsmap[S, fldname]
+ cname = Constant('data', lltype.Void)
+ newop = SpaceOperation(opname,
+ [v, cname],
+ op.result)
+ self.newops.append(newop)
+ elif op.opname in ("ptr_iszero", "ptr_nonzero"):
+ # we know the pointer is not NULL if it comes from
+ # a successful malloc
+ c = Constant(op.opname == "ptr_nonzero", lltype.Bool)
+ newop = SpaceOperation('same_as', [c], op.result)
+ self.newops.append(newop)
+ else:
+ raise AssertionError, op.opname
+
+
+ def insert_keepalives(self, newvars):
+ if self.last_removed_access is not None:
keepalives = []
- for v in list_newvars():
+ for v in newvars:
T = v.concretetype
if isinstance(T, lltype.Ptr) and T._needsgc():
v0 = Variable()
v0.concretetype = lltype.Void
newop = SpaceOperation('keepalive', [v], v0)
keepalives.append(newop)
- newops[last_removed_access:last_removed_access] = keepalives
-
- block.operations[:] = newops
+ self.newops[self.last_removed_access:self.last_removed_access] = keepalives
class OOTypeMallocRemover(BaseMallocRemover):
- pass # TODO
-def remove_simple_mallocs(graph, type_system='lltype'):
- if type_system == 'lltype':
+ IDENTITY_OPS = ('same_as', 'ooupcast', 'oodowncast')
+ SUBSTRUCT_OPS = ()
+ MALLOC_OP = 'new'
+ FIELD_ACCESS = dict.fromkeys(["oogetfield",
+ "oosetfield",
+ "oononnull",
+ #"oois", # ???
+ #"instanceof", # ???
+ ])
+ SUBSTRUCT_ACCESS = {}
+ CHECK_ARRAY_INDEX = {}
+
+ def get_STRUCT(self, TYPE):
+ return TYPE
+
+ def union_wrapper(self, S):
+ return False
+
+ def RTTI_dtor(self, STRUCT):
+ return False
+
+ def _get_fields(self, TYPE):
+ if isinstance(TYPE, ootype.Record):
+ return TYPE._fields
+ elif isinstance(TYPE, ootype.Instance):
+ return TYPE._allfields()
+ else:
+ assert False
+
+ def flatten(self, TYPE):
+ for name, (FIELDTYPE, default) in self._get_fields(TYPE).iteritems():
+ key = TYPE, name
+ example = FIELDTYPE._defl()
+ constant = Constant(example)
+ constant.concretetype = FIELDTYPE
+ self.flatconstants[key] = constant
+ self.flatnames.append(key)
+ self.newvarstype[key] = FIELDTYPE
+
+ def key_for_field_access(self, S, fldname):
+ return S, fldname
+
+ def flowin_op(self, op, vars, newvarsmap):
+ if op.opname == "oogetfield":
+ S = op.args[0].concretetype
+ fldname = op.args[1].value
+ key = self.key_for_field_access(S, fldname)
+ newop = SpaceOperation("same_as",
+ [newvarsmap[key]],
+ op.result)
+ self.newops.append(newop)
+ last_removed_access = len(self.newops)
+ elif op.opname == "oosetfield":
+ S = op.args[0].concretetype
+ fldname = op.args[1].value
+ key = self.key_for_field_access(S, fldname)
+ assert key in newvarsmap
+ newvarsmap[key] = op.args[2]
+ last_removed_access = len(self.newops)
+ elif op.opname in ("same_as", "oodowncast", "ooupcast"):
+ assert op.result not in vars
+ vars[op.result] = True
+ # Consider the two pointers (input and result) as
+ # equivalent. We can, and indeed must, use the same
+ # flattened list of variables for both, as a "setfield"
+ # via one pointer must be reflected in the other.
+ elif op.opname == "oononnull":
+ # we know the pointer is not NULL if it comes from
+ # a successful malloc
+ c = Constant(True, lltype.Bool)
+ newop = SpaceOperation('same_as', [c], op.result)
+ self.newops.append(newop)
+ else:
+ raise AssertionError, op.opname
+
+ def insert_keepalives(self, newvars):
+ pass
+
+def remove_simple_mallocs(graph, type_system='lltypesystem'):
+ if type_system == 'lltypesystem':
remover = LLTypeMallocRemover()
else:
remover = OOTypeMallocRemover()
Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py Tue Jan 9 13:11:19 2007
@@ -1,7 +1,7 @@
import py
from pypy.translator.backendopt.all import backend_optimizations
from pypy.translator.backendopt.support import md5digest
-from pypy.translator.backendopt.test.test_malloc import check_malloc_removed
+from pypy.translator.backendopt.test.test_malloc import TestLLTypeMallocRemoval as LLTypeMallocRemovalTest
from pypy.translator.translator import TranslationContext, graphof
from pypy.objspace.flow.model import Constant
from pypy.annotation import model as annmodel
@@ -9,6 +9,8 @@
from pypy.rlib.rarithmetic import intmask
from pypy import conftest
+check_malloc_removed = LLTypeMallocRemovalTest.check_malloc_removed
+
def translateopt(func, sig, **optflags):
t = TranslationContext()
t.buildannotator().build_types(func, sig)
Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Tue Jan 9 13:11:19 2007
@@ -1,5 +1,5 @@
import py
-from pypy.translator.backendopt.malloc import LLTypeMallocRemover
+from pypy.translator.backendopt.malloc import LLTypeMallocRemover, OOTypeMallocRemover
from pypy.translator.backendopt.inline import inline_function
from pypy.translator.backendopt.all import backend_optimizations
from pypy.translator.translator import TranslationContext, graphof
@@ -7,311 +7,337 @@
from pypy.objspace.flow.model import checkgraph, flatten, Block, mkentrymap
from pypy.rpython.llinterp import LLInterpreter
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.ootypesystem import ootype
from pypy.rlib import objectmodel
from pypy.conftest import option
-
-def check_malloc_removed(graph):
- remover = LLTypeMallocRemover()
- checkgraph(graph)
- count1 = count2 = 0
- for node in flatten(graph):
- if isinstance(node, Block):
- for op in node.operations:
- if op.opname == 'malloc':
- S = op.args[0].value
- if not remover.union_wrapper(S): # union wrappers are fine
- count1 += 1
- if op.opname in ('direct_call', 'indirect_call'):
- count2 += 1
- assert count1 == 0 # number of mallocs left
- assert count2 == 0 # number of calls left
-
-def check(fn, signature, args, expected_result, must_be_removed=True):
- remover = LLTypeMallocRemover()
- t = TranslationContext()
- t.buildannotator().build_types(fn, signature)
- t.buildrtyper().specialize()
- graph = graphof(t, fn)
- if option.view:
- t.view()
- # to detect missing keepalives and broken intermediate graphs,
- # we do the loop ourselves instead of calling remove_simple_mallocs()
- while True:
- progress = remover.remove_mallocs_once(graph)
- simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()))
- if progress and option.view:
+class BaseMallocRemovalTest(object):
+ type_system = None
+ MallocRemover = None
+
+ def _skip_oo(self, msg):
+ if self.type_system == 'ootype':
+ py.test.skip(msg)
+
+ def check_malloc_removed(cls, graph):
+ remover = cls.MallocRemover()
+ checkgraph(graph)
+ count1 = count2 = 0
+ for node in flatten(graph):
+ if isinstance(node, Block):
+ for op in node.operations:
+ if op.opname == cls.MallocRemover.MALLOC_OP:
+ S = op.args[0].value
+ if not remover.union_wrapper(S): # union wrappers are fine
+ count1 += 1
+ if op.opname in ('direct_call', 'indirect_call'):
+ count2 += 1
+ assert count1 == 0 # number of mallocs left
+ assert count2 == 0 # number of calls left
+ check_malloc_removed = classmethod(check_malloc_removed)
+
+ def check(self, fn, signature, args, expected_result, must_be_removed=True):
+ remover = self.MallocRemover()
+ t = TranslationContext()
+ t.buildannotator().build_types(fn, signature)
+ t.buildrtyper(type_system=self.type_system).specialize()
+ graph = graphof(t, fn)
+ if option.view:
t.view()
- if expected_result is not Ellipsis:
- interp = LLInterpreter(t.rtyper)
- res = interp.eval_graph(graph, args)
- assert res == expected_result
- if not progress:
- break
- if must_be_removed:
- check_malloc_removed(graph)
- return graph
-
-
-def test_fn1():
- def fn1(x, y):
- if x > 0:
- t = x+y, x-y
- else:
- t = x-y, x+y
- s, d = t
- return s*d
- check(fn1, [int, int], [15, 10], 125)
-
-def test_fn2():
- class T:
- pass
- def fn2(x, y):
- t = T()
- t.x = x
- t.y = y
- if x > 0:
- return t.x + t.y
- else:
- return t.x - t.y
- check(fn2, [int, int], [-6, 7], -13)
-
-def test_fn3():
- def fn3(x):
- a, ((b, c), d, e) = x+1, ((x+2, x+3), x+4, x+5)
- return a+b+c+d+e
- check(fn3, [int], [10], 65)
-
-def test_fn4():
- class A:
- pass
- class B(A):
- pass
- def fn4(i):
- a = A()
- b = B()
- a.b = b
- b.i = i
- return a.b.i
- check(fn4, [int], [42], 42)
-
-def test_fn5():
- class A:
- attr = 666
- class B(A):
- attr = 42
- def fn5():
- b = B()
- return b.attr
- check(fn5, [], [], 42)
-
-def test_aliasing():
- class A:
- pass
- def fn6(n):
- a1 = A()
- a1.x = 5
- a2 = A()
- a2.x = 6
- if n > 0:
- a = a1
- else:
- a = a2
- a.x = 12
- return a1.x
- check(fn6, [int], [1], 12, must_be_removed=False)
-
-def test_with_keepalive():
- from pypy.rlib.objectmodel import keepalive_until_here
- def fn1(x, y):
- if x > 0:
- t = x+y, x-y
- else:
- t = x-y, x+y
- s, d = t
- keepalive_until_here(t)
- return s*d
- check(fn1, [int, int], [15, 10], 125)
-
-def test_dont_remove_with__del__():
- import os
- delcalls = [0]
- class A(object):
- nextid = 0
- def __init__(self):
- self.id = self.nextid
- self.nextid += 1
-
- def __del__(self):
- delcalls[0] += 1
- os.write(1, "__del__\n")
-
- def f(x=int):
- a = A()
- i = 0
- while i < x:
+ # to detect missing keepalives and broken intermediate graphs,
+ # we do the loop ourselves instead of calling remove_simple_mallocs()
+ while True:
+ progress = remover.remove_mallocs_once(graph)
+ simplify.transform_dead_op_vars_in_blocks(list(graph.iterblocks()))
+ if progress and option.view:
+ t.view()
+ if expected_result is not Ellipsis:
+ interp = LLInterpreter(t.rtyper)
+ res = interp.eval_graph(graph, args)
+ assert res == expected_result
+ if not progress:
+ break
+ if must_be_removed:
+ self.check_malloc_removed(graph)
+ return graph
+
+ def test_fn1(self):
+ def fn1(x, y):
+ if x > 0:
+ t = x+y, x-y
+ else:
+ t = x-y, x+y
+ s, d = t
+ return s*d
+ self.check(fn1, [int, int], [15, 10], 125)
+
+ def test_fn2(self):
+ class T:
+ pass
+ def fn2(x, y):
+ t = T()
+ t.x = x
+ t.y = y
+ if x > 0:
+ return t.x + t.y
+ else:
+ return t.x - t.y
+ self.check(fn2, [int, int], [-6, 7], -13)
+
+ def test_fn3(self):
+ def fn3(x):
+ a, ((b, c), d, e) = x+1, ((x+2, x+3), x+4, x+5)
+ return a+b+c+d+e
+ self.check(fn3, [int], [10], 65)
+
+ def test_fn4(self):
+ class A:
+ pass
+ class B(A):
+ pass
+ def fn4(i):
+ a = A()
+ b = B()
+ a.b = b
+ b.i = i
+ return a.b.i
+ self.check(fn4, [int], [42], 42)
+
+ def test_fn5(self):
+ self._skip_oo('It will work as soon as trivial oosend are inlined')
+ class A:
+ attr = 666
+ class B(A):
+ attr = 42
+ def fn5():
+ b = B()
+ return b.attr
+ self.check(fn5, [], [], 42)
+
+ def test_aliasing(self):
+ class A:
+ pass
+ def fn6(n):
+ a1 = A()
+ a1.x = 5
+ a2 = A()
+ a2.x = 6
+ if n > 0:
+ a = a1
+ else:
+ a = a2
+ a.x = 12
+ return a1.x
+ self.check(fn6, [int], [1], 12, must_be_removed=False)
+
+
+
+class TestLLTypeMallocRemoval(BaseMallocRemovalTest):
+ type_system = 'lltype'
+ MallocRemover = LLTypeMallocRemover
+
+ def test_with_keepalive(self):
+ from pypy.rlib.objectmodel import keepalive_until_here
+ def fn1(x, y):
+ if x > 0:
+ t = x+y, x-y
+ else:
+ t = x-y, x+y
+ s, d = t
+ keepalive_until_here(t)
+ return s*d
+ self.check(fn1, [int, int], [15, 10], 125)
+
+ def test_dont_remove_with__del__(self):
+ import os
+ delcalls = [0]
+ class A(object):
+ nextid = 0
+ def __init__(self):
+ self.id = self.nextid
+ self.nextid += 1
+
+ def __del__(self):
+ delcalls[0] += 1
+ os.write(1, "__del__\n")
+
+ def f(x=int):
+ a = A()
+ i = 0
+ while i < x:
+ a = A()
+ os.write(1, str(delcalls[0]) + "\n")
+ i += 1
+ return 1
+ t = TranslationContext()
+ t.buildannotator().build_types(f, [int])
+ t.buildrtyper().specialize()
+ graph = graphof(t, f)
+ backend_optimizations(t)
+ op = graph.startblock.exits[0].target.exits[1].target.operations[0]
+ assert op.opname == "malloc"
+
+ def test_add_keepalives(self):
+ class A:
+ pass
+ SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
+ BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
+ def fn7(i):
+ big = lltype.malloc(BIG)
a = A()
- os.write(1, str(delcalls[0]) + "\n")
- i += 1
- return 1
- t = TranslationContext()
- t.buildannotator().build_types(f, [int])
- t.buildrtyper().specialize()
- graph = graphof(t, f)
- backend_optimizations(t)
- op = graph.startblock.exits[0].target.exits[1].target.operations[0]
- assert op.opname == "malloc"
-
-def test_add_keepalives():
- class A:
- pass
- SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
- def fn7(i):
- big = lltype.malloc(BIG)
- a = A()
- a.big = big
- a.small = big.s
- a.small.x = 0
- while i > 0:
- a.small.x += i
- i -= 1
- return a.small.x
- check(fn7, [int], [10], 55, must_be_removed=False)
-
-def test_getsubstruct():
- SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
-
- def fn(n1, n2):
- b = lltype.malloc(BIG)
- b.z = n1
- b.s.x = n2
- return b.z - b.s.x
-
- check(fn, [int, int], [100, 58], 42)
-
-def test_fixedsizearray():
- A = lltype.FixedSizeArray(lltype.Signed, 3)
- S = lltype.GcStruct('S', ('a', A))
-
- def fn(n1, n2):
- s = lltype.malloc(S)
- a = s.a
- a[0] = n1
- a[2] = n2
- return a[0]-a[2]
-
- check(fn, [int, int], [100, 42], 58)
-
-def test_wrapper_cannot_be_removed():
- SMALL = lltype.OpaqueType('SMALL')
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
-
- def g(small):
- return -1
- def fn():
- b = lltype.malloc(BIG)
- g(b.s)
-
- check(fn, [], [], None, must_be_removed=False)
-
-def test_direct_fieldptr():
- S = lltype.GcStruct('S', ('x', lltype.Signed))
-
- def fn():
- s = lltype.malloc(S)
- s.x = 11
- p = lltype.direct_fieldptr(s, 'x')
- return p[0]
-
- check(fn, [], [], 11)
-
-def test_direct_fieldptr_2():
- T = lltype.GcStruct('T', ('z', lltype.Signed))
- S = lltype.GcStruct('S', ('t', T),
- ('x', lltype.Signed),
- ('y', lltype.Signed))
- def fn():
- s = lltype.malloc(S)
- s.x = 10
- s.t.z = 1
- px = lltype.direct_fieldptr(s, 'x')
- py = lltype.direct_fieldptr(s, 'y')
- pz = lltype.direct_fieldptr(s.t, 'z')
- py[0] = 31
- return px[0] + s.y + pz[0]
-
- check(fn, [], [], 42)
-
-def test_getarraysubstruct():
- U = lltype.Struct('U', ('n', lltype.Signed))
- for length in [1, 2]:
- S = lltype.GcStruct('S', ('a', lltype.FixedSizeArray(U, length)))
- for index in range(length):
-
- def fn():
- s = lltype.malloc(S)
- s.a[index].n = 12
- return s.a[index].n
- check(fn, [], [], 12)
-
-def test_ptr_nonzero():
- S = lltype.GcStruct('S')
- def fn():
- s = lltype.malloc(S)
- return bool(s)
- check(fn, [], [], True)
-
-def test_substruct_not_accessed():
- SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
- BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
- def fn():
- x = lltype.malloc(BIG)
- while x.z < 10: # makes several blocks
- x.z += 3
- return x.z
- check(fn, [], [], 12)
-
-def test_union():
- UNION = lltype.Struct('UNION', ('a', lltype.Signed), ('b', lltype.Signed),
- hints = {'union': True})
- BIG = lltype.GcStruct('BIG', ('u1', UNION), ('u2', UNION))
- def fn():
- x = lltype.malloc(BIG)
- x.u1.a = 3
- x.u2.b = 6
- return x.u1.b * x.u2.a
- check(fn, [], [], Ellipsis)
-
-def test_keep_all_keepalives():
- SIZE = llmemory.sizeof(lltype.Signed)
- PARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))
- class A:
- def __init__(self):
- self.addr = llmemory.raw_malloc(SIZE)
- def __del__(self):
- llmemory.raw_free(self.addr)
- class B:
- pass
- def myfunc():
- b = B()
- b.keep = A()
- b.data = llmemory.cast_adr_to_ptr(b.keep.addr, PARRAY)
- b.data[0] = 42
- ptr = b.data
- # normally 'b' could go away as early as here, which would free
- # the memory held by the instance of A in b.keep...
- res = ptr[0]
- # ...so we explicitly keep 'b' alive until here
- objectmodel.keepalive_until_here(b)
- return res
- graph = check(myfunc, [], [], 42,
- must_be_removed=False) # 'A' instance left
-
- # there is a getarrayitem near the end of the graph of myfunc.
- # However, the memory it accesses must still be protected by the
- # following keepalive, even after malloc removal
- entrymap = mkentrymap(graph)
- [link] = entrymap[graph.returnblock]
- assert link.prevblock.operations[-1].opname == 'keepalive'
+ a.big = big
+ a.small = big.s
+ a.small.x = 0
+ while i > 0:
+ a.small.x += i
+ i -= 1
+ return a.small.x
+ self.check(fn7, [int], [10], 55, must_be_removed=False)
+
+ def test_getsubstruct(self):
+ SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
+ BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
+
+ def fn(n1, n2):
+ b = lltype.malloc(BIG)
+ b.z = n1
+ b.s.x = n2
+ return b.z - b.s.x
+
+ self.check(fn, [int, int], [100, 58], 42)
+
+ def test_fixedsizearray(self):
+ A = lltype.FixedSizeArray(lltype.Signed, 3)
+ S = lltype.GcStruct('S', ('a', A))
+
+ def fn(n1, n2):
+ s = lltype.malloc(S)
+ a = s.a
+ a[0] = n1
+ a[2] = n2
+ return a[0]-a[2]
+
+ self.check(fn, [int, int], [100, 42], 58)
+
+ def test_wrapper_cannot_be_removed(self):
+ SMALL = lltype.OpaqueType('SMALL')
+ BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
+
+ def g(small):
+ return -1
+ def fn():
+ b = lltype.malloc(BIG)
+ g(b.s)
+
+ self.check(fn, [], [], None, must_be_removed=False)
+
+ def test_direct_fieldptr(self):
+ S = lltype.GcStruct('S', ('x', lltype.Signed))
+
+ def fn():
+ s = lltype.malloc(S)
+ s.x = 11
+ p = lltype.direct_fieldptr(s, 'x')
+ return p[0]
+
+ self.check(fn, [], [], 11)
+
+ def test_direct_fieldptr_2(self):
+ T = lltype.GcStruct('T', ('z', lltype.Signed))
+ S = lltype.GcStruct('S', ('t', T),
+ ('x', lltype.Signed),
+ ('y', lltype.Signed))
+ def fn():
+ s = lltype.malloc(S)
+ s.x = 10
+ s.t.z = 1
+ px = lltype.direct_fieldptr(s, 'x')
+ py = lltype.direct_fieldptr(s, 'y')
+ pz = lltype.direct_fieldptr(s.t, 'z')
+ py[0] = 31
+ return px[0] + s.y + pz[0]
+
+ self.check(fn, [], [], 42)
+
+ def test_getarraysubstruct(self):
+ U = lltype.Struct('U', ('n', lltype.Signed))
+ for length in [1, 2]:
+ S = lltype.GcStruct('S', ('a', lltype.FixedSizeArray(U, length)))
+ for index in range(length):
+
+ def fn():
+ s = lltype.malloc(S)
+ s.a[index].n = 12
+ return s.a[index].n
+ self.check(fn, [], [], 12)
+
+ def test_ptr_nonzero(self):
+ S = lltype.GcStruct('S')
+ def fn():
+ s = lltype.malloc(S)
+ return bool(s)
+ self.check(fn, [], [], True)
+
+ def test_substruct_not_accessed(self):
+ SMALL = lltype.Struct('SMALL', ('x', lltype.Signed))
+ BIG = lltype.GcStruct('BIG', ('z', lltype.Signed), ('s', SMALL))
+ def fn():
+ x = lltype.malloc(BIG)
+ while x.z < 10: # makes several blocks
+ x.z += 3
+ return x.z
+ self.check(fn, [], [], 12)
+
+ def test_union(self):
+ UNION = lltype.Struct('UNION', ('a', lltype.Signed), ('b', lltype.Signed),
+ hints = {'union': True})
+ BIG = lltype.GcStruct('BIG', ('u1', UNION), ('u2', UNION))
+ def fn():
+ x = lltype.malloc(BIG)
+ x.u1.a = 3
+ x.u2.b = 6
+ return x.u1.b * x.u2.a
+ self.check(fn, [], [], Ellipsis)
+
+ def test_keep_all_keepalives(self):
+ SIZE = llmemory.sizeof(lltype.Signed)
+ PARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))
+ class A:
+ def __init__(self):
+ self.addr = llmemory.raw_malloc(SIZE)
+ def __del__(self):
+ llmemory.raw_free(self.addr)
+ class B:
+ pass
+ def myfunc():
+ b = B()
+ b.keep = A()
+ b.data = llmemory.cast_adr_to_ptr(b.keep.addr, PARRAY)
+ b.data[0] = 42
+ ptr = b.data
+ # normally 'b' could go away as early as here, which would free
+ # the memory held by the instance of A in b.keep...
+ res = ptr[0]
+ # ...so we explicitly keep 'b' alive until here
+ objectmodel.keepalive_until_here(b)
+ return res
+ graph = self.check(myfunc, [], [], 42,
+ must_be_removed=False) # 'A' instance left
+
+ # there is a getarrayitem near the end of the graph of myfunc.
+ # However, the memory it accesses must still be protected by the
+ # following keepalive, even after malloc removal
+ entrymap = mkentrymap(graph)
+ [link] = entrymap[graph.returnblock]
+ assert link.prevblock.operations[-1].opname == 'keepalive'
+
+class TestOOTypeMallocRemoval(BaseMallocRemovalTest):
+ type_system = 'ootype'
+ MallocRemover = OOTypeMallocRemover
+
+ def test_oononnull(self):
+ FOO = ootype.Instance('Foo', ootype.ROOT)
+ def fn():
+ s = ootype.new(FOO)
+ return bool(s)
+ self.check(fn, [], [], True)
From antocuni at codespeak.net Tue Jan 9 13:14:06 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 9 Jan 2007 13:14:06 +0100 (CET)
Subject: [pypy-svn] r36344 - pypy/dist/pypy/translator
Message-ID: <20070109121406.38A6A10075@code0.codespeak.net>
Author: antocuni
Date: Tue Jan 9 13:13:57 2007
New Revision: 36344
Modified:
pypy/dist/pypy/translator/driver.py
Log:
Use malloc removal by default when translating to CLI.
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Tue Jan 9 13:13:57 2007
@@ -357,6 +357,7 @@
if self.config.translation.backend == 'cli':
opt['merge_if_blocks'] = True
opt['inline_threshold'] = 1
+ opt['mallocs'] = True
backend_optimizations(self.translator, **opt)
#
task_backendopt_ootype = taskdef(task_backendopt_ootype,
From arigo at codespeak.net Tue Jan 9 13:58:04 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 13:58:04 +0100 (CET)
Subject: [pypy-svn] r36349 - in pypy/dist/pypy: rlib/rctypes
rlib/rctypes/test rpython
Message-ID: <20070109125804.0D5F21006E@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 13:58:01 2007
New Revision: 36349
Added:
pypy/dist/pypy/rlib/rctypes/rfunc.py (contents, props changed)
pypy/dist/pypy/rlib/rctypes/test/test_rfunc.py
- copied, changed from r36147, pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
Modified:
pypy/dist/pypy/rlib/rctypes/implementation.py
pypy/dist/pypy/rlib/rctypes/rstruct.py
pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
pypy/dist/pypy/rpython/controllerentry.py
Log:
Fix constructor args for ctypes.Structures.
Started working on ctypes functions, not really working so far.
Modified: pypy/dist/pypy/rlib/rctypes/implementation.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/implementation.py (original)
+++ pypy/dist/pypy/rlib/rctypes/implementation.py Tue Jan 9 13:58:01 2007
@@ -46,8 +46,11 @@
_controller_ = cls
register_for_metatype = classmethod(register_for_metatype)
+ def ctypecheck(self, x):
+ return isinstance(x, self.ctype)
+
def convert(self, x):
- if isinstance(x, self.ctype):
+ if self.ctypecheck(x):
key = "by_id", id(x)
else:
key = "by_value", x
@@ -120,7 +123,10 @@
class CTypesObjEntry(ControllerEntryForPrebuilt):
def getcontroller(self):
- ctype = self.type
+ if hasattr(self._controller_, 'real_ctype_of'):
+ ctype = self._controller_.real_ctype_of(self.instance)
+ else:
+ ctype = self.type
return _build_controller(self._controller_, ctype)
TLS = tlsobject()
@@ -202,3 +208,4 @@
import pypy.rlib.rctypes.rstruct
import pypy.rlib.rctypes.rbuiltin
import pypy.rlib.rctypes.rchar_p
+import pypy.rlib.rctypes.rfunc
Added: pypy/dist/pypy/rlib/rctypes/rfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/rctypes/rfunc.py Tue Jan 9 13:58:01 2007
@@ -0,0 +1,71 @@
+from pypy.annotation import model as annmodel
+from pypy.rlib.rctypes.implementation import CTypeController, getcontroller
+from pypy.rlib.rctypes import rctypesobject
+from pypy.rpython.lltypesystem import lltype
+
+import ctypes
+
+CFuncPtrType = type(ctypes.CFUNCTYPE(None))
+
+
+class FuncPtrCTypeController(CTypeController):
+ ready = 0
+
+ def __init__(self, ctype):
+ CTypeController.__init__(self, ctype)
+ sample_instance = self.ctype()
+ self.argtypes = sample_instance.argtypes
+ self.restype = sample_instance.restype
+ self.knowntype = rctypesobject.RPointer(None)
+
+ def setup(self):
+ if self.ready == 0:
+ self.ready = 1
+ self.argscontrollers = [getcontroller(a) for a in self.argtypes]
+ self.rescontroller = getcontroller(self.restype)
+ argscls = [c.knowntype for c in self.argscontrollers]
+ rescls = self.rescontroller.knowntype
+ self.rfunctype = rctypesobject.RFuncType(argscls, rescls)
+ self.knowntype.setpointertype(self.rfunctype, force=True)
+ self.make_helpers()
+ self.ready = 2
+
+ def make_helpers(self):
+ # XXX need stuff to unwrap pointer boxes to lltype pointers
+ pass
+
+ def real_ctype_of(fnptr):
+ # in ctypes, most function pointers have argtypes and restype set
+ # on the function pointer object itself, not on its class
+ return ctypes.CFUNCTYPE(fnptr.restype, *fnptr.argtypes)
+ real_ctype_of = staticmethod(real_ctype_of)
+
+ def ctypecheck(self, x):
+ return (isinstance(type(x), CFuncPtrType) and
+ tuple(x.argtypes) == tuple(self.argtypes) and
+ x.restype == self.restype)
+
+ def new(self):
+ obj = self.knowntype.allocate()
+ return obj
+
+ def initialize_prebuilt(self, ptrobj, cfuncptr):
+ if not cfuncptr: # passed as arg to functions expecting func pointers
+ return
+ # XXX this assumes it is an external function, correctly initialized
+ # with includes and libraries attributes
+ name = cfuncptr.__name__
+ includes = getattr(cfuncptr, 'includes', ())
+ libraries = getattr(cfuncptr, 'libraries', ())
+ rlib = rctypesobject.RLibrary(libraries, includes)
+ llinterp_friendly_version = getattr(cfuncptr,
+ 'llinterp_friendly_version',
+ None)
+ funcobj = self.rfunctype.fromlib(rlib, name, llinterp_friendly_version)
+ ptrobj.set_contents(funcobj)
+
+ def call(self, fnptrobj, *args):
+ return fnptrobj.get_contents().call(*args)
+
+
+FuncPtrCTypeController.register_for_metatype(CFuncPtrType)
Modified: pypy/dist/pypy/rlib/rctypes/rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/rstruct.py Tue Jan 9 13:58:01 2007
@@ -1,3 +1,4 @@
+from pypy.annotation import model as annmodel
from pypy.rlib.rctypes.implementation import CTypeController, getcontroller
from pypy.rlib.rctypes import rctypesobject
from pypy.rpython.extregistry import ExtRegistryEntry
@@ -84,10 +85,12 @@
while len(lst) <= index:
lst.append(None)
if lst[index] is not None:
- raise TypeError("duplicate value for argument %r" % name)
+ from pypy.rpython.error import TyperError
+ raise TyperError("duplicate value for argument %r" % name)
lst[index] = value
if kwds:
- raise TypeError("unknown keyword(s): %r" % (kwds.keys(),))
+ from pypy.rpython.error import TyperError
+ raise TyperError("unknown keyword(s): %r" % (kwds.keys(),))
return lst
def ctrl_new_ex(self, bookkeeper, *args_s, **kwds_s):
@@ -148,7 +151,7 @@
assert s_fieldname.is_constant()
ofs = offsetof(s_Struct.const, s_fieldname.const)
assert ofs >= 0
- s_result = SomeInteger(nonneg=True)
+ s_result = annmodel.SomeInteger(nonneg=True)
s_result.const = ofs
return s_result
Modified: pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py
==============================================================================
--- pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py (original)
+++ pypy/dist/pypy/rlib/rctypes/test/test_rstruct.py Tue Jan 9 13:58:01 2007
@@ -5,6 +5,7 @@
import py.test
import pypy.rlib.rctypes.implementation
from pypy.rlib.rctypes.test.test_rprimitive import BaseTestAnnotation
+from pypy.rpython.error import TyperError
from pypy.rpython.test.test_llinterp import interpret
from pypy.translator.c.test.test_genc import compile
from pypy.rlib.rctypes.rstruct import offsetof
@@ -179,7 +180,6 @@
assert res == 289
def test_specialize_constructor_args(self):
- #py.test.skip("in-progress")
class S(Structure):
_fields_ = [('x', c_int),
('y', c_char)]
@@ -201,7 +201,6 @@
assert res == 463
def test_specialize_bad_constructor_args(self):
- py.test.skip("in-progress")
class S(Structure):
_fields_ = [('x', c_int),
('y', c_char)]
@@ -214,7 +213,6 @@
py.test.raises(TyperError, "interpret(f2, [4])")
def test_specialize_offsetof(self):
- py.test.skip("in-progress")
def f1():
return offsetof(tagpoint, 'y')
res = interpret(f1, [])
Modified: pypy/dist/pypy/rpython/controllerentry.py
==============================================================================
--- pypy/dist/pypy/rpython/controllerentry.py (original)
+++ pypy/dist/pypy/rpython/controllerentry.py Tue Jan 9 13:58:01 2007
@@ -124,6 +124,13 @@
from pypy.rpython.rcontrollerentry import rtypedelegate
return rtypedelegate(self.is_true, hop)
+ def ctrl_call(self, s_obj, *args_s):
+ return delegate(self.call, s_obj, *args_s)
+
+ def rtype_call(self, hop):
+ from pypy.rpython.rcontrollerentry import rtypedelegate
+ return rtypedelegate(self.call, hop)
+
def delegate(boundmethod, *args_s):
bk = getbookkeeper()
@@ -218,6 +225,9 @@
def is_true(s_cin):
return s_cin.controller.ctrl_is_true(s_cin.s_real_obj)
+ def simple_call(s_cin, *args_s):
+ return s_cin.controller.ctrl_call(s_cin.s_real_obj, *args_s)
+
class __extend__(pairtype(SomeControlledInstance, annmodel.SomeObject)):
From arigo at codespeak.net Tue Jan 9 13:58:29 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 13:58:29 +0100 (CET)
Subject: [pypy-svn] r36350 - pypy/dist/pypy/objspace
Message-ID: <20070109125829.2028D1006E@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 13:58:28 2007
New Revision: 36350
Modified:
pypy/dist/pypy/objspace/taint.py
Log:
For now, hide the error message from the TaintError, as this can reveal
secret information.
Modified: pypy/dist/pypy/objspace/taint.py
==============================================================================
--- pypy/dist/pypy/objspace/taint.py (original)
+++ pypy/dist/pypy/objspace/taint.py Tue Jan 9 13:58:28 2007
@@ -34,7 +34,7 @@
def explode(self, space):
msg = self.operr.errorstr(space)
- raise OperationError(space.w_TaintError, space.wrap(msg))
+ raise OperationError(space.w_TaintError, space.w_None) # space.wrap(msg))
def taint(w_obj):
From arigo at codespeak.net Tue Jan 9 14:00:56 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 14:00:56 +0100 (CET)
Subject: [pypy-svn] r36351 - in pypy/dist/pypy/jit/codegen: . i386
Message-ID: <20070109130056.1EE5F1006E@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 14:00:54 2007
New Revision: 36351
Modified:
pypy/dist/pypy/jit/codegen/i386/conftest.py
pypy/dist/pypy/jit/codegen/i386/rgenop.py
pypy/dist/pypy/jit/codegen/model.py
Log:
(mwh, arigo)
Couple of minor tweaks. The codegen/i386 tests pass again.
Modified: pypy/dist/pypy/jit/codegen/i386/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/conftest.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/conftest.py Tue Jan 9 14:00:54 2007
@@ -5,7 +5,6 @@
class Directory(py.test.collect.Directory):
def run(self):
- import py; py.test.skip("in-progress")
try:
processor = detect_cpu.autodetect()
except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/dist/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/rgenop.py Tue Jan 9 14:00:54 2007
@@ -905,9 +905,6 @@
def add_case(self, gv_case):
return self.replay_builder
- def add_default(self):
- return self.replay_builder
-
class ReplayBuilder(GenBuilder):
def __init__(self, rgenop):
@@ -963,10 +960,10 @@
def enter_next_block(self, kinds, args_gv):
return None
- def jump_if_false(self, gv_condition):
+ def jump_if_false(self, gv_condition, args_gv):
return self
- def jump_if_true(self, gv_condition):
+ def jump_if_true(self, gv_condition, args_gv):
return self
def finish_and_return(self, sigtoken, gv_returnvar):
@@ -975,8 +972,9 @@
def finish_and_goto(self, outputargs_gv, target):
pass
- def flexswitch(self, gv_exitswitch):
- return ReplayFlexSwitch(self)
+ def flexswitch(self, gv_exitswitch, args_gv):
+ flexswitch = ReplayFlexSwitch(self)
+ return flexswitch, self
def show_incremental_progress(self):
pass
Modified: pypy/dist/pypy/jit/codegen/model.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/model.py (original)
+++ pypy/dist/pypy/jit/codegen/model.py Tue Jan 9 14:00:54 2007
@@ -95,6 +95,7 @@
Returns an instance of GenLabel that can later be jumped to.
'''
+ raise NotImplementedError
def jump_if_false(self, gv_condition, args_for_jump_gv):
'''Make a fresh builder, insert in the current block a
@@ -106,13 +107,16 @@
easier it must be closed before the fresh builder is used at
all, and the first thing to call on the latter is
start_writing().'''
+ raise NotImplementedError
def jump_if_true(self, gv_condition, args_for_jump_gv):
'''See above, with the obvious difference :)'''
+ raise NotImplementedError
def finish_and_return(self, sigtoken, gv_returnvar):
'''Emit the epilogue code for the function, and the code to
return gv_returnvar. This "closes" the current builder.'''
+ raise NotImplementedError
def finish_and_goto(self, outputargs_gv, target):
'''Insert an unconditional jump to target.
@@ -125,6 +129,7 @@
This "closes" the current builder.
'''
+ raise NotImplementedError
def flexswitch(self, gv_exitswitch, args_gv):
'''The Fun Stuff.
@@ -143,6 +148,7 @@
This "closes" the current builder.
'''
+ raise NotImplementedError
def show_incremental_progress(self):
'''Give some indication of the code that this instance has generated.
@@ -187,6 +193,7 @@
entrypoint is the address of the new function as GenConst and
inputargs_gv is the location of each argument on entry to the
function. name is for debugging purposes"""
+ raise NotImplementedError
# all staticmethods commented out for the sake of the annotator
@@ -215,6 +222,7 @@
The purpose of this is to reconstruct the knowledge of the
locations of the GenVars at some later point in the code, any
code actually generated during replaying is thrown away.'''
+ raise NotImplementedError
#@staticmethod
#def erasedType(T):
@@ -273,3 +281,4 @@
def add_case(self, gv_case):
'''Make a new builder that will be jumped to when the
switched-on GenVar takes the value of the GenConst gv_case.'''
+ raise NotImplementedError
From fijal at codespeak.net Tue Jan 9 14:34:38 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Tue, 9 Jan 2007 14:34:38 +0100 (CET)
Subject: [pypy-svn] r36354 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070109133438.C25CF1007D@code0.codespeak.net>
Author: fijal
Date: Tue Jan 9 14:34:28 2007
New Revision: 36354
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
Log:
From cfbolz at codespeak.net Tue Jan 9 15:24:45 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 9 Jan 2007 15:24:45 +0100 (CET)
Subject: [pypy-svn] r36356 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070109142445.3ACCD1007A@code0.codespeak.net>
Author: cfbolz
Date: Tue Jan 9 15:24:44 2007
New Revision: 36356
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
Log:
(all): status update
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt Tue Jan 9 15:24:44 2007
@@ -11,49 +11,51 @@
* Arre
* Samuele
* Carl Friedrich
-
-later
------
-
* Laura
* Jacob
* Alexandre
* Sylvain
* Niko
+
+later
+-----
+
* Eric
+
Tasks
=====
-
-
JIT
---
-* "virtual frames"
+* "virtual frames" (Samuele, Arre): funfunfun. basic test is working,
+ manually written virtualizable structs can be change within the jit-generated
+ code and the changes are seen from outside. IN-PROGRESS
- write a small interpreter that shows the performance problems without having
to use the full pypy
- actually implement support for this in the rtyper and the jit...
-* have register allocation
-
-(Michael, Armin, Arre, Samuele)
+* have register allocation (Michael, Armin): IN-PROGRESS: redesigned the backend
+ interface a bit, adapted the llgraph and i386 backends to the changes. now:
+ fixing llvm and ppc backends
py.test and the py-lib
----------------------
* polish the code and documentation of the py lib, and eventually
- release it (Holger and Maciek to investigate)
+ release it IN-PROGRESS (Holger, Maciek)
-* integrate api-doc and source-viewer on the py-lib web-page
+* integrate api-doc and source-viewer on the py-lib web-page IN-PROGRESS
-* use source-viewer on more code? pypy?
+* use source-viewer on more code? pypy? IN-PROGRESS
-* provide code search facility
+* debian packaging for the py-lib: HUGE PROGRESS (Alexandre, Sylvain)
+* (provide code search facility)
interpreter prototypes
@@ -71,7 +73,8 @@
Integration and Configuration
-----------------------------
-* actually use the build tool during the sprint (Guido, Carl Friedrich)
+* actually use the build tool during the sprint (Guido, Carl Friedrich): DONE
+ WITH BUGS
* think about py-lib and pypy debian packaging
@@ -84,13 +87,14 @@
Other
-----
-* progress on the JavaScript interpreter (Leonardo, Antonio)
+* progress on the JavaScript interpreter (Leonardo, Antonio): IN-PROGRESS, the
+ JS intepreter translates
* Java backend
* discuss refinement interface for external functions
-* (make py-lib run on pypy-c)
+* (make py-lib run on pypy-c) PROGRESS: the compiler problems are fixed
Discussions during the sprint
From cfbolz at codespeak.net Tue Jan 9 15:35:32 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 9 Jan 2007 15:35:32 +0100 (CET)
Subject: [pypy-svn] r36357 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070109143532.21C4410083@code0.codespeak.net>
Author: cfbolz
Date: Tue Jan 9 15:35:31 2007
New Revision: 36357
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
Log:
(all) planning for today
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt Tue Jan 9 15:35:31 2007
@@ -38,9 +38,9 @@
- actually implement support for this in the rtyper and the jit...
-* have register allocation (Michael, Armin): IN-PROGRESS: redesigned the backend
- interface a bit, adapted the llgraph and i386 backends to the changes. now:
- fixing llvm and ppc backends
+* have register allocation (Michael, half Armin): IN-PROGRESS: redesigned the
+ backend interface a bit, adapted the llgraph and i386 backends to the
+ changes. now: fixing llvm and ppc backends
py.test and the py-lib
@@ -50,6 +50,7 @@
release it IN-PROGRESS (Holger, Maciek)
* integrate api-doc and source-viewer on the py-lib web-page IN-PROGRESS
+ (Guido, Maciek around)
* use source-viewer on more code? pypy? IN-PROGRESS
@@ -87,8 +88,8 @@
Other
-----
-* progress on the JavaScript interpreter (Leonardo, Antonio): IN-PROGRESS, the
- JS intepreter translates
+* progress on the JavaScript interpreter (Leonardo, half Armin): IN-PROGRESS,
+ the JS intepreter translates
* Java backend
@@ -100,13 +101,13 @@
Discussions during the sprint
=============================
-* status of wp6 and wp12
-
-* wp9 + wp10 + wp11 discussion
-
-* eu-report meeting
+* eu meeting: thursday 5pm
+ - status and plans for wp6 and wp12
+ - wp9 + wp10 + wp11 discussion
+ - eu-report meeting
* pycon talk discussion
-* release plannings
+* release plannings: saturday 5pm
+* pypy and py-lib debian packaging discussion: thursday morning 10am
From antocuni at codespeak.net Tue Jan 9 15:37:03 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Tue, 9 Jan 2007 15:37:03 +0100 (CET)
Subject: [pypy-svn] r36358 - pypy/dist/pypy/translator/backendopt/test
Message-ID: <20070109143703.8DA6610086@code0.codespeak.net>
Author: antocuni
Date: Tue Jan 9 15:37:03 2007
New Revision: 36358
Modified:
pypy/dist/pypy/translator/backendopt/test/test_all.py
Log:
make test_all working with ootype too.
Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py Tue Jan 9 15:37:03 2007
@@ -2,6 +2,7 @@
from pypy.translator.backendopt.all import backend_optimizations
from pypy.translator.backendopt.support import md5digest
from pypy.translator.backendopt.test.test_malloc import TestLLTypeMallocRemoval as LLTypeMallocRemovalTest
+from pypy.translator.backendopt.test.test_malloc import TestOOTypeMallocRemoval as OOTypeMallocRemovalTest
from pypy.translator.translator import TranslationContext, graphof
from pypy.objspace.flow.model import Constant
from pypy.annotation import model as annmodel
@@ -9,17 +10,6 @@
from pypy.rlib.rarithmetic import intmask
from pypy import conftest
-check_malloc_removed = LLTypeMallocRemovalTest.check_malloc_removed
-
-def translateopt(func, sig, **optflags):
- t = TranslationContext()
- t.buildannotator().build_types(func, sig)
- t.buildrtyper().specialize()
- if conftest.option.view:
- t.view()
- backend_optimizations(t, **optflags)
- return t
-
class A:
def __init__(self, x, y):
self.bounds = (x, y)
@@ -50,160 +40,182 @@
return firstthat(myfunction, condition)
-def test_big():
- assert big() == 83
-
- t = translateopt(big, [], inline_threshold=100, mallocs=True)
-
- big_graph = graphof(t, big)
- check_malloc_removed(big_graph)
-
- interp = LLInterpreter(t.rtyper)
- res = interp.eval_graph(big_graph, [])
- assert res == 83
-
-
-def test_for_loop():
- def f(n):
- total = 0
- for i in range(n):
- total += i
- return total
-
- t = translateopt(f, [int], inline_threshold=1, mallocs=True)
- # this also checks that the BASE_INLINE_THRESHOLD is enough for 'for' loops
-
- f_graph = graph = graphof(t, f)
- check_malloc_removed(f_graph)
-
- interp = LLInterpreter(t.rtyper)
- res = interp.eval_graph(f_graph, [11])
- assert res == 55
-
-
-def test_list_comp():
- def f(n1, n2):
- c = [i for i in range(n2)]
- return 33
-
- t = translateopt(f, [int, int], inline_threshold=10, mallocs=True)
-
- f_graph = graphof(t, f)
- check_malloc_removed(f_graph)
+class BaseTester(object):
+ type_system = None
- interp = LLInterpreter(t.rtyper)
- res = interp.eval_graph(f_graph, [11, 22])
- assert res == 33
-
-
-def test_premature_death():
- import os
- from pypy.annotation.listdef import s_list_of_strings
-
- inputtypes = [s_list_of_strings]
-
- def debug(msg):
- os.write(2, "debug: " + msg + '\n')
-
- def entry_point(argv):
- #debug("entry point starting")
- for arg in argv:
- #debug(" argv -> " + arg)
- r = arg.replace('_', '-')
- #debug(' replaced -> ' + r)
- a = r.lower()
- #debug(" lowered -> " + a)
- return 0
-
- t = translateopt(entry_point, inputtypes, inline_threshold=1, mallocs=True)
-
- entry_point_graph = graphof(t, entry_point)
-
- argv = t.rtyper.getrepr(inputtypes[0]).convert_const(['./pypy-c'])
+ def translateopt(self, func, sig, **optflags):
+ t = TranslationContext()
+ t.buildannotator().build_types(func, sig)
+ t.buildrtyper(type_system=self.type_system).specialize()
+ if conftest.option.view:
+ t.view()
+ backend_optimizations(t, **optflags)
+ if conftest.option.view:
+ t.view()
+ return t
+
+ def test_big(self):
+ assert big() == 83
+
+ t = self.translateopt(big, [], inline_threshold=100, mallocs=True)
+
+ big_graph = graphof(t, big)
+ self.check_malloc_removed(big_graph)
+
+ interp = LLInterpreter(t.rtyper)
+ res = interp.eval_graph(big_graph, [])
+ assert res == 83
+
+
+ def test_for_loop(self):
+ def f(n):
+ total = 0
+ for i in range(n):
+ total += i
+ return total
+
+ t = self.translateopt(f, [int], inline_threshold=1, mallocs=True)
+ # this also checks that the BASE_INLINE_THRESHOLD is enough for 'for' loops
+
+ f_graph = graph = graphof(t, f)
+ self.check_malloc_removed(f_graph)
+
+ interp = LLInterpreter(t.rtyper)
+ res = interp.eval_graph(f_graph, [11])
+ assert res == 55
+
+ def test_premature_death(self):
+ import os
+ from pypy.annotation.listdef import s_list_of_strings
+
+ inputtypes = [s_list_of_strings]
+
+ def debug(msg):
+ os.write(2, "debug: " + msg + '\n')
+
+ def entry_point(argv):
+ #debug("entry point starting")
+ for arg in argv:
+ #debug(" argv -> " + arg)
+ r = arg.replace('_', '-')
+ #debug(' replaced -> ' + r)
+ a = r.lower()
+ #debug(" lowered -> " + a)
+ return 0
- interp = LLInterpreter(t.rtyper)
- interp.eval_graph(entry_point_graph, [argv])
+ t = self.translateopt(entry_point, inputtypes, inline_threshold=1, mallocs=True)
+ entry_point_graph = graphof(t, entry_point)
-def test_idempotent():
- def s(x):
- res = 0
- i = 1
- while i <= x:
- res += i
- i += 1
- return res
+ argv = t.rtyper.getrepr(inputtypes[0]).convert_const(['./pypy-c'])
- def g(x):
- return s(100) + s(1) + x
+ interp = LLInterpreter(t.rtyper)
+ interp.eval_graph(entry_point_graph, [argv])
- def idempotent(n1, n2):
- c = [i for i in range(n2)]
- return 33 + big() + g(10)
- t = translateopt(idempotent, [int, int], raisingop2direct_call=True,
- constfold=False)
- digest1 = md5digest(t)
+ def test_idempotent(self):
+ def s(x):
+ res = 0
+ i = 1
+ while i <= x:
+ res += i
+ i += 1
+ return res
- digest2 = md5digest(t)
- assert digest1 == digest2
+ def g(x):
+ return s(100) + s(1) + x
- #XXX Inlining and constfold are currently non-idempotent.
- # Maybe they just renames variables but the graph changes in some way.
- backend_optimizations(t, raisingop2direct_call=True,
- inline_threshold=0, constfold=False)
- digest3 = md5digest(t)
- assert digest1 == digest3
+ def idempotent(n1, n2):
+ c = [i for i in range(n2)]
+ return 33 + big() + g(10)
+ t = self.translateopt(idempotent, [int, int], raisingop2direct_call=True,
+ constfold=False)
+ digest1 = md5digest(t)
-def test_bug_inlined_if():
- def f(x, flag):
- if flag:
- y = x
- else:
- y = x+1
- return y*5
- def myfunc(x):
- return f(x, False) - f(x, True)
+ digest2 = md5digest(t)
+ assert digest1 == digest2
- assert myfunc(10) == 5
+ #XXX Inlining and constfold are currently non-idempotent.
+ # Maybe they just renames variables but the graph changes in some way.
+ backend_optimizations(t, raisingop2direct_call=True,
+ inline_threshold=0, constfold=False)
+ digest3 = md5digest(t)
+ assert digest1 == digest3
- t = translateopt(myfunc, [int], inline_threshold=100)
- interp = LLInterpreter(t.rtyper)
- res = interp.eval_graph(graphof(t, myfunc), [10])
- assert res == 5
-def test_range_iter():
- def fn(start, stop, step):
- res = 0
- if step == 0:
- if stop >= start:
- r = range(start, stop, 1)
+ def test_bug_inlined_if(self):
+ def f(x, flag):
+ if flag:
+ y = x
else:
- r = range(start, stop, -1)
- else:
- r = range(start, stop, step)
- for i in r:
- res = res * 51 + i
- return res
- t = translateopt(fn, [int, int, int], merge_if_blocks=True)
- interp = LLInterpreter(t.rtyper)
- for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
- assert interp.eval_graph(graphof(t, fn), args) == intmask(fn(*args))
-
-def test_constant_diffuse():
- def g(x,y):
- if x < 0:
- return 0
- return x + y
-
- def f(x):
- return g(x,7)+g(x,11)
-
- t = translateopt(f, [int])
- fgraph = graphof(t, f)
-
- for link in fgraph.iterlinks():
- assert Constant(7) not in link.args
- assert Constant(11) not in link.args
+ y = x+1
+ return y*5
+ def myfunc(x):
+ return f(x, False) - f(x, True)
+
+ assert myfunc(10) == 5
+
+ t = self.translateopt(myfunc, [int], inline_threshold=100)
+ interp = LLInterpreter(t.rtyper)
+ res = interp.eval_graph(graphof(t, myfunc), [10])
+ assert res == 5
+
+ def test_range_iter(self):
+ def fn(start, stop, step):
+ res = 0
+ if step == 0:
+ if stop >= start:
+ r = range(start, stop, 1)
+ else:
+ r = range(start, stop, -1)
+ else:
+ r = range(start, stop, step)
+ for i in r:
+ res = res * 51 + i
+ return res
+ t = self.translateopt(fn, [int, int, int], merge_if_blocks=True)
+ interp = LLInterpreter(t.rtyper)
+ for args in [2, 7, 0], [7, 2, 0], [10, 50, 7], [50, -10, -3]:
+ assert interp.eval_graph(graphof(t, fn), args) == intmask(fn(*args))
+
+ def test_constant_diffuse(self):
+ def g(x,y):
+ if x < 0:
+ return 0
+ return x + y
+
+ def f(x):
+ return g(x,7)+g(x,11)
+
+ t = self.translateopt(f, [int])
+ fgraph = graphof(t, f)
+
+ for link in fgraph.iterlinks():
+ assert Constant(7) not in link.args
+ assert Constant(11) not in link.args
+
+class TestLLType(BaseTester):
+ type_system = 'lltype'
+ check_malloc_removed = LLTypeMallocRemovalTest.check_malloc_removed
+
+ def test_list_comp(self):
+ def f(n1, n2):
+ c = [i for i in range(n2)]
+ return 33
+
+ t = self.translateopt(f, [int, int], inline_threshold=10, mallocs=True)
+
+ f_graph = graphof(t, f)
+ self.check_malloc_removed(f_graph)
+
+ interp = LLInterpreter(t.rtyper)
+ res = interp.eval_graph(f_graph, [11, 22])
+ assert res == 33
+
+class TestOOType(BaseTester):
+ type_system = 'ootype'
+ check_malloc_removed = OOTypeMallocRemovalTest.check_malloc_removed
+ def test_big(self):
+ py.test.skip('FIXME! It should pass as long as oosend is inlined')
From arigo at codespeak.net Tue Jan 9 16:00:11 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Tue, 9 Jan 2007 16:00:11 +0100 (CET)
Subject: [pypy-svn] r36360 - pypy/dist/pypy/jit/codegen/llvm
Message-ID: <20070109150011.938FF10079@code0.codespeak.net>
Author: arigo
Date: Tue Jan 9 16:00:09 2007
New Revision: 36360
Added:
pypy/dist/pypy/jit/codegen/llvm/conftest.py
- copied unchanged from r36307, pypy/dist/pypy/jit/codegen/llvm/conftest.py
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
Log:
Adapt jit/codegen/llvm to the new rgenop interface.
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Tue Jan 9 16:00:09 2007
@@ -309,13 +309,15 @@
self.cases.append('%s,label %%%s' % (gv_case.operand(), targetbuilder.nextlabel))
log('%s FlexSwitch.add_case %s => %s' % (
self.builder.block.label, gv_case.operand(), targetbuilder.nextlabel))
+ targetbuilder.start_writing()
return targetbuilder
- def add_default(self):
+ def _add_default(self):
targetbuilder = self.builder._fork()
self.default_label = targetbuilder.nextlabel
log('%s FlexSwitch.add_default => %s' % (
self.builder.block.label, targetbuilder.nextlabel))
+ targetbuilder.start_writing()
return targetbuilder
def writecode(self, lines):
@@ -324,7 +326,7 @@
self.gv_exitswitch.operand(), self.default_label, ' '.join(self.cases)))
-class Builder(object): #changed baseclass from (GenBuilder) for better error messages
+class Builder(GenBuilder):
def __init__(self, rgenop, coming_from):
self.rgenop = rgenop
@@ -342,11 +344,24 @@
def end(self):
self.rgenop.end() # XXX Hack to be removed!
- def pause(self):
- log('%s Builder.pause' % self.block.label)
-
- def resume(self):
- log('%s Builder.resume' % self.block.label)
+ def pause_writing(self, args_gv):
+ log('%s Builder.pause_writing' % self.block.label)
+ assert self.asm is not None
+ self.nextlabel = count.newlabel() # for the next block
+ self.asm.append(' br label %%%s' % (self.nextlabel,))
+ self.asm = None
+ return self
+
+ def start_writing(self):
+ log('%s Builder.start_writing' % self.nextlabel)
+ assert self.nextlabel is not None
+ coming_from = self.block
+ # prepare the next block
+ nextblock = BasicBlock(self.rgenop, self.nextlabel, [])
+ self.block = nextblock
+ self.asm = nextblock.asm
+ self.nextlabel = None
+ nextblock.add_incoming_link(coming_from, [])
# ----------------------------------------------------------------
# The public Builder interface
@@ -589,24 +604,19 @@
#/XXX
def enter_next_block(self, kinds, args_gv):
- # if nextlabel is None, it means that we still need to
- # properly terminate the current block (with a br to go
- # to the next block)
- # see: http://llvm.org/docs/LangRef.html#terminators
- if self.nextlabel is None:
- self.nextlabel = count.newlabel()
- self.asm.append(' br label %%%s' % (self.nextlabel,))
+ assert self.nextlabel is None
coming_from = self.block
- log('%s Builder leave block %s' % (
- coming_from.label, [v.operand() for v in args_gv]))
-
+ newlabel = count.newlabel()
+ # we still need to properly terminate the current block
+ # (with a br to go to the next block)
+ # see: http://llvm.org/docs/LangRef.html#terminators
+ self.asm.append(' br label %%%s' % (newlabel,))
# prepare the next block
- nextblock = BasicBlock(self.rgenop, self.nextlabel, kinds)
+ nextblock = BasicBlock(self.rgenop, newlabel, kinds)
log('%s Builder enter block %s' % (
nextblock.label, [v.operand() for v in nextblock.inputargs]))
- self.block = nextblock
- self.asm = nextblock.asm
- self.nextlabel = None
+ self.block = nextblock
+ self.asm = nextblock.asm
# link the two blocks together and update args_gv
nextblock.add_incoming_link(coming_from, args_gv)
@@ -615,20 +625,22 @@
return self.block
- def jump_if_false(self, gv_condition):
+ def jump_if_false(self, gv_condition, args_for_jump_gv):
log('%s Builder.jump_if_false %s' % (self.block.label, gv_condition.operand()))
targetbuilder = self._fork()
self.nextlabel = count.newlabel()
self.asm.append(' br %s,label %%%s,label %%%s' % (
gv_condition.operand(), self.nextlabel, targetbuilder.nextlabel))
+ self.start_writing()
return targetbuilder
- def jump_if_true(self, gv_condition):
+ def jump_if_true(self, gv_condition, args_for_jump_gv):
log('%s Builder.jump_if_true %s' % (self.block.label, gv_condition.operand()))
targetbuilder = self._fork()
self.nextlabel = count.newlabel()
self.asm.append(' br %s,label %%%s,label %%%s' % (
gv_condition.operand(), targetbuilder.nextlabel, self.nextlabel))
+ self.start_writing()
return targetbuilder
def _is_false(self, gv_x, nullstr='0'):
@@ -857,9 +869,10 @@
target.add_incoming_link(self.block, outputargs_gv)
self._close()
- def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch, args_gv):
log('%s Builder.flexswitch %s' % (self.block.label, gv_exitswitch.operand()))
- return FlexSwitch(self.rgenop, self, gv_exitswitch)
+ flexswitch = FlexSwitch(self.rgenop, self, gv_exitswitch)
+ return flexswitch, flexswitch._add_default()
class RLLVMGenOp(object): #changed baseclass from (AbstractRGenOp) for better error messages
@@ -926,7 +939,7 @@
self.funcsig[n] = '%s %%%s' % (restype, name)
self.gv_entrypoint = IntConst(n) #note: updated by Builder.end() (i.e after compilation)
args = list(prologueblock.inputargs)
- builder.enter_next_block(argtypes, args)
+ builder.start_writing()
return builder, self.gv_entrypoint, args
@specialize.genconst(1)
From pedronis at codespeak.net Tue Jan 9 16:09:53 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 9 Jan 2007 16:09:53 +0100 (CET)
Subject: [pypy-svn] r36365 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070109150953.A9D0510082@code0.codespeak.net>
Author: pedronis
Date: Tue Jan 9 16:09:50 2007
New Revision: 36365
Modified:
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
let the effect on the virtualizable struct be stored back such that they can be seen outside the jitted world.
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Tue Jan 9 16:09:50 2007
@@ -290,6 +290,7 @@
builder, gv_generated, inputargs_gv = rgenop.newgraph(sigtoken,
"generated")
cache[key] = gv_generated
+ top_jitstate = fresh_jitstate(builder)
i = 0
for color, _, make_arg_redbox in args_specification:
if color == "green":
@@ -299,15 +300,14 @@
else:
llvalue = args[0]
args = args[1:]
- box = make_arg_redbox(inputargs_gv, i)
+ box = make_arg_redbox(top_jitstate, inputargs_gv, i)
i += make_arg_redbox.consumes
portal_ts_args += (box,)
- top_jitstate = fresh_jitstate(builder)
top_jitstate = portal_fn(top_jitstate, *portal_ts_args)
if top_jitstate is not None:
finish_jitstate(top_jitstate, sigtoken)
-
+
builder.end()
builder.show_incremental_progress()
fn = gv_generated.revealconst(lltype.Ptr(FUNC))
@@ -1459,7 +1459,7 @@
kind = self.hrtyper.RGenOp.kindToken(TYPE)
boxcls = rvalue.ll_redboxcls(TYPE)
- def make_arg_redbox(inputargs_gv, i):
+ def make_arg_redbox(jitstate, inputargs_gv, i):
gv_arg = inputargs_gv[i]
box = boxcls(kind, gv_arg)
return box
@@ -1515,8 +1515,9 @@
typedesc = self.gettypedesc()
- def make_arg_redbox(inputargs_gv, i):
+ def make_arg_redbox(jitstate, inputargs_gv, i):
box = typedesc.factory()
+ jitstate.add_virtualizable(box)
j = 1
content = box.content
assert isinstance(content, rcontainer.VirtualStruct)
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Tue Jan 9 16:09:50 2007
@@ -328,6 +328,14 @@
def force_runtime_container(self, builder):
assert 0, "not implemented for now"
+ def store_back(self, builder):
+ fielddescs = self.typedesc.fielddescs
+ boxes = self.content_boxes
+ gv_outside = boxes[-1].genvar
+ for i in range(1, len(fielddescs)):
+ fielddesc = fielddescs[i]
+ box = boxes[i]
+ fielddesc.generate_set(builder, gv_outside, box)
# ____________________________________________________________
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Tue Jan 9 16:09:50 2007
@@ -240,6 +240,8 @@
def retrieve_jitstate_for_merge(states_dic, jitstate, key, global_resumer,
force_merge=False):
+ if jitstate.virtualizables:
+ jitstate.enter_block_sweep_virtualizables()
if key not in states_dic:
states_dic[key] = []
start_new_block(states_dic, jitstate, key, global_resumer)
@@ -324,8 +326,8 @@
node = resuming.path.pop()
assert isinstance(node, PromotionPathSplit)
return node.answer
- locals_gv = jitstate.get_locals_gv()
- later_builder = jitstate.curbuilder.jump_if_false(exitgvar, locals_gv)
+ false_gv = jitstate.get_locals_gv() # alive gvs on the false path
+ later_builder = jitstate.curbuilder.jump_if_false(exitgvar, false_gv)
jitstate2 = jitstate.split(later_builder, resumepoint, list(greens_gv))
if resuming is None:
node = jitstate.promotion_path
@@ -623,9 +625,7 @@
if gv_switchvar.is_const:
return False
else:
- incoming = []
- memo = rvalue.enter_block_memo()
- jitstate.enter_block(incoming, memo)
+ incoming = jitstate.enter_block_sweep_virtualizables()
switchblock = enter_next_block(jitstate, incoming)
gv_switchvar = promotebox.genvar
incoming_gv = [box.genvar for box in incoming]
@@ -748,6 +748,7 @@
#fz_frame = ... set by freeze()
#fz_exc_type_box = ... set by freeze()
#fz_exc_value_box = ... set by freeze()
+ #fz_virtualizables = ... set by freeze()
def exactmatch(self, jitstate, outgoingvarboxes, memo):
fullmatch = True
@@ -769,7 +770,13 @@
frame = self.fz_frame .unfreeze(incomingvarboxes, memo)
exc_type_box = self.fz_exc_type_box .unfreeze(incomingvarboxes, memo)
exc_value_box = self.fz_exc_value_box.unfreeze(incomingvarboxes, memo)
- return JITState(None, frame, exc_type_box, exc_value_box)
+ virtualizables = {}
+ for fz_virtualizable_box in self.fz_virtualizables:
+ virtualizable_box = fz_virtualizable_box.unfreeze(incomingvarboxes,
+ memo)
+ virtualizables[virtualizable_box] = None
+ return JITState(None, frame, exc_type_box, exc_value_box,
+ virtualizables=virtualizables)
class VirtualFrame(object):
@@ -816,7 +823,8 @@
promotion_path = None
def __init__(self, builder, frame, exc_type_box, exc_value_box,
- resumepoint=-1, newgreens=[], resuming=None):
+ resumepoint=-1, newgreens=[], resuming=None,
+ virtualizables=None):
self.curbuilder = builder
self.frame = frame
self.exc_type_box = exc_type_box
@@ -824,45 +832,80 @@
self.resumepoint = resumepoint
self.greens = newgreens
self.resuming = resuming # None or a ResumingInfo
+ if virtualizables is None:
+ virtualizables = {}
+ self.virtualizables = virtualizables
+
+ def add_virtualizable(self, virtualizable_box):
+ self.virtualizables[virtualizable_box] = None
def split(self, newbuilder, newresumepoint, newgreens):
memo = rvalue.copy_memo()
+ virtualizables = {}
+ for virtualizable_box in self.virtualizables:
+ virtualizables[virtualizable_box.copy(memo)] = None
later_jitstate = JITState(newbuilder,
self.frame.copy(memo),
self.exc_type_box .copy(memo),
self.exc_value_box.copy(memo),
newresumepoint,
newgreens,
- self.resuming)
+ self.resuming,
+ virtualizables)
# add the later_jitstate to the chain of pending-for-dispatch_next()
dispatchqueue = self.frame.dispatchqueue
later_jitstate.next = dispatchqueue.split_chain
dispatchqueue.split_chain = later_jitstate
return later_jitstate
- def enter_block(self, incoming, memo):
+ def _enter_block(self, incoming, memo):
self.frame.enter_block(incoming, memo)
self.exc_type_box .enter_block(incoming, memo)
self.exc_value_box.enter_block(incoming, memo)
+ def enter_block_sweep_virtualizables(self):
+ incoming = []
+ memo = rvalue.enter_block_memo()
+ self._enter_block(incoming, memo)
+ virtualizables = self.virtualizables
+ builder = self.curbuilder
+ for virtualizable_box in virtualizables.keys():
+ if virtualizable_box.content not in memo.containers:
+ del virtualizables[virtualizable_box]
+ assert isinstance(virtualizable_box, rvalue.PtrRedBox)
+ content = virtualizable_box.content
+ assert isinstance(content, rcontainer.VirtualizableStruct)
+ content.store_back(builder)
+ return incoming
+
def freeze(self, memo):
result = FrozenJITState()
result.fz_frame = self.frame.freeze(memo)
result.fz_exc_type_box = self.exc_type_box .freeze(memo)
result.fz_exc_value_box = self.exc_value_box.freeze(memo)
+ fz_virtualizables = result.fz_virtualizables = {}
+ for virtualizable_box in self.virtualizables:
+ assert virtualizable_box in memo.boxes
+ fz_virtualizables[virtualizable_box.freeze(memo)] = None
return result
def replace(self, memo):
self.frame.replace(memo)
self.exc_type_box = self.exc_type_box .replace(memo)
self.exc_value_box = self.exc_value_box.replace(memo)
-
- def get_locals_gv(self):
+ virtualizables = {}
+ for virtualizable_box in self.virtualizables:
+ virtualizables[virtualizable_box.replace(memo)] = None
+ self.virtualizables = virtualizables
+
+ def get_locals_gv(self): # xxx
# get all the genvars that are "alive", i.e. stored in the JITState
# or the VirtualFrames
incoming = []
memo = rvalue.enter_block_memo()
- self.enter_block(incoming, memo)
+ self._enter_block(incoming, memo)
+ for virtualizable_box in self.virtualizables:
+ virtualizable_box.enter_block(incoming, memo)
locals_gv = [redbox.genvar for redbox in incoming]
return locals_gv
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Tue Jan 9 16:09:50 2007
@@ -83,7 +83,43 @@
res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
assert res == 21
- self.check_insns(getfield=0, setfield=0)
+ self.check_insns(getfield=0)
+ residual_graph = self.get_residual_graph()
+ assert len(residual_graph.startblock.inputargs) == 3
+ assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
+ [lltype.Ptr(XY), lltype.Signed, lltype.Signed])
+
+ def test_explicit_set_effect(self):
+
+ def f(xy):
+ xy_access = xy.access
+ if xy_access:
+ x = xy_access.get_x(xy)
+ else:
+ x = xy.x
+ xy_access = xy.access
+ if xy_access:
+ xy_access.set_y(xy, 1)
+ else:
+ xy.y = 3
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ return x+y
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ v = f(xy)
+ return v + xy.y
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 26
+ self.check_insns(getfield=0)
residual_graph = self.get_residual_graph()
assert len(residual_graph.startblock.inputargs) == 3
assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
From santagada at codespeak.net Tue Jan 9 16:31:30 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Tue, 9 Jan 2007 16:31:30 +0100 (CET)
Subject: [pypy-svn] r36369 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070109153130.9114810079@code0.codespeak.net>
Author: santagada
Date: Tue Jan 9 16:31:28 2007
New Revision: 36369
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
finishing the machinery to have a dynamic interpreter
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Tue Jan 9 16:31:28 2007
@@ -7,11 +7,21 @@
# TODO Add line info for debug
# def __init__(self, lineno = 1):
# self.lineno = lineno
- pass
+ def eval(self, ctx):
+ raise NotImplementedError
-class Statement(Node):
def execute(self, ctx):
raise NotImplementedError
+
+ def get_literal(self):
+ raise NotImplementedError
+
+ def get_args(self, ctx):
+ raise NotImplementedError
+
+
+class Statement(Node):
+ pass
class Expression(Statement):
def eval(self, ctx):
@@ -31,6 +41,9 @@
s2 = self.left.eval(ctx).GetValue()
s4 = self.right.eval(ctx).GetValue()
return self.decision(ctx, s2, s4)
+
+ def decision(self, ctx, op1, op2):
+ raise NotImplementedError
class BinaryLogicOp(BinaryOp):
@@ -40,35 +53,27 @@
def writer(x):
print x
+def load_source(script_source):
+ temp_tree = parse(script_source)
+ return from_tree(temp_tree)
+
+def load_bytecode(bytecode):
+ temp_tree = parse_bytecode(bytecode)
+ return from_tree(temp_tree)
+
class Interpreter(object):
"""Creates a js interpreter"""
- def __init__(self, script_source=None):
+ def __init__(self):
self.w_Object = W_Object() #creating Object
self.w_Global = W_Object()
self.w_Global.Prototype = self.w_Object
self.w_Global.Put('prototype', W_String('Object'))
self.w_Global.Put('Object', self.w_Object)
self.global_context = global_context(self.w_Global)
- if script_source is not None:
- self.load_source(script_source)
-
- def load_source(self, script_source):
- """load a source script text to the interpreter"""
- temp_tree = parse(script_source)
- self.script = from_tree(temp_tree)
-
- def append_source(self, script_source):
- temp_tree = parse(script_source)
- newscript = from_tree(temp_tree)
- self.script.append_script(newscript)
-
- def load_bytecode(self, bytecode):
- temp_tree = parse_bytecode(bytecode)
- self.script = from_tree(temp_tree)
- def run(self):
+ def run(self, script):
"""run the interpreter"""
- return self.script.execute(self.global_context)
+ return script.execute(self.global_context)
class PropertyInit(Node):
def __init__(self, name, value):
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Tue Jan 9 16:31:28 2007
@@ -55,9 +55,18 @@
def ToNumber(self):
return NaN
- # def get_literal(self):
- # return self.ToString()
- #
+ def Get(self, P):
+ raise NotImplementedError
+
+ def Put(self, P, V, DontDelete=False, ReadOnly=False, DontEnum=False, Internal=False):
+ raise NotImplementedError
+
+ def PutValue(self, w, ctx):
+ raise NotImplementedError
+
+ def Call(self, ctx, args=[], this=None):
+ raise NotImplementedError
+
def __str__(self):
return self.ToString()
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Tue Jan 9 16:31:28 2007
@@ -28,16 +28,20 @@
def assert_prints(self, code, assval):
l = []
interpreter.writer = l.append
- js_int = interpreter.Interpreter(code)
+ js_int = interpreter.Interpreter()
try:
- js_int.run()
+ if isinstance(code, str):
+ js_int.run(load_source(code))
+ else:
+ for codepiece in code:
+ js_int.run(load_source(codepiece))
except ThrowException, excpt:
l.append("uncaught exception: "+str(excpt.exception))
assert l == assval
def assert_result(self, code, result):
- inter = interpreter.Interpreter(code)
- r = inter.run()
+ inter = interpreter.Interpreter()
+ r = inter.run(load_source(code))
assert r.ToString() == result.ToString()
def test_interp_parse(self):
@@ -283,5 +287,15 @@
print("z" in x);
""", ["true", "false"])
+ def test_append_code(self):
+ self.assert_prints(["""
+ var x; x=3;
+ """, """
+ print(x);
+ z = 2;
+ ""","""
+ print(z)
+ """]
+ ,["3", "2"])
From santagada at codespeak.net Tue Jan 9 16:32:03 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Tue, 9 Jan 2007 16:32:03 +0100 (CET)
Subject: [pypy-svn] r36370 - pypy/dist/pypy/translator/goal
Message-ID: <20070109153203.8154110086@code0.codespeak.net>
Author: santagada
Date: Tue Jan 9 16:32:02 2007
New Revision: 36370
Modified:
pypy/dist/pypy/translator/goal/targetjsstandalone.py
Log:
changes to make it work with multiscripts
Modified: pypy/dist/pypy/translator/goal/targetjsstandalone.py
==============================================================================
--- pypy/dist/pypy/translator/goal/targetjsstandalone.py (original)
+++ pypy/dist/pypy/translator/goal/targetjsstandalone.py Tue Jan 9 16:32:02 2007
@@ -15,8 +15,7 @@
def entry_point(argv):
if len(argv) == 2:
f = open_file_as_stream(argv[1])
- interp.load_bytecode(f.readall())
- interp.run()
+ interp.run(load_bytecode(f.readall()))
return 0
elif argv[0] == 'foo':
raise ExecutionReturned(None)
From niko at codespeak.net Tue Jan 9 16:53:40 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Tue, 9 Jan 2007 16:53:40 +0100 (CET)
Subject: [pypy-svn] r36372 - pypy/dist/pypy/translator/jvm
Message-ID: <20070109155340.0FC7B1007D@code0.codespeak.net>
Author: niko
Date: Tue Jan 9 16:53:38 2007
New Revision: 36372
Modified:
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/node.py
Log:
fix two tests:
1. default field values
2. recursive pbc
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Tue Jan 9 16:53:38 2007
@@ -95,38 +95,39 @@
# Create class object if it does not already exist:
if OOTYPE in self._classes:
return self._classes[OOTYPE]
-
- # Resolve super class first
- assert OOTYPE._superclass
- supercls = self.pending_class(OOTYPE._superclass)
- # Create the class object
+ # Create the class object first
clsnm = self._pkg(self._uniq(OOTYPE._name))
- clsobj = node.Class(clsnm, supercls)
-
- print "Class %s has super %s" % (
- clsnm, supercls.name)
-
- # Store the class object for future calls
+ clsobj = node.Class(clsnm)
self._classes[OOTYPE] = clsobj
+ # Resolve super class
+ assert OOTYPE._superclass
+ supercls = self.pending_class(OOTYPE._superclass)
+ clsobj.set_super_class(supercls)
+
# TODO --- mangle field and method names? Must be
# deterministic, or use hashtable to avoid conflicts between
# classes?
# Add fields:
for fieldnm, (FIELDOOTY, fielddef) in OOTYPE._fields.iteritems():
- print "Class %s has field %s of type %s" % (
- clsobj.name, fieldnm, FIELDOOTY)
if FIELDOOTY is ootype.Void: continue
fieldty = self.lltype_to_cts(FIELDOOTY)
- clsobj.add_field(jvmgen.Field(clsnm, fieldnm, fieldty, False))
+ clsobj.add_field(
+ jvmgen.Field(clsnm, fieldnm, fieldty, False, FIELDOOTY),
+ fielddef)
# Add methods:
for mname, mimpl in OOTYPE._methods.iteritems():
if not hasattr(mimpl, 'graph'):
# Abstract method
- TODO
+ METH = mimpl._TYPE
+ arglist = [self.lltype_to_cts(ARG) for ARG in METH.ARGS
+ if ARG is not ootype.Void]
+ returntype = self.lltype_to_cts(METH.RESULT)
+ clsobj.add_abstract_method(jvmgen.Method.v(
+ clsobj, mname, arglist, returntype))
else:
# if the first argument's type is not a supertype of
# this class it means that this method this method is
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Tue Jan 9 16:53:38 2007
@@ -276,7 +276,8 @@
# methobj is its Method instance.
class Method(object):
-
+
+ # Create a virtual method:
def v(classty, methnm, argtypes, rettype):
"""
Shorthand to create a virtual method.
@@ -288,12 +289,10 @@
"""
assert isinstance(classty, JvmType)
classnm = classty.name
- argtypes = [a.descriptor for a in argtypes]
- rettype = rettype.descriptor
- return Method(classnm, methnm, desc_for_method(argtypes, rettype),
- opcode=INVOKEVIRTUAL)
+ return Method(classnm, methnm, argtypes, rettype, opcode=INVOKEVIRTUAL)
v = staticmethod(v)
+ # Create a static method:
def s(classty, methnm, argtypes, rettype):
"""
Shorthand to create a static method.
@@ -305,16 +304,20 @@
"""
assert isinstance(classty, JvmType)
classnm = classty.name
- argtypes = [a.descriptor for a in argtypes]
- rettype = rettype.descriptor
- return Method(classnm, methnm, desc_for_method(argtypes, rettype))
+ return Method(classnm, methnm, argtypes, rettype)
s = staticmethod(s)
- def __init__(self, classnm, methnm, desc, opcode=INVOKESTATIC):
+ def __init__(self, classnm, methnm, argtypes, rettype, opcode=INVOKESTATIC):
self.opcode = opcode
self.class_name = classnm # String, ie. "java.lang.Math"
self.method_name = methnm # String "abs"
- self.descriptor = desc # String, (I)I
+ self.argument_types = argtypes # List of jvmtypes
+ self.return_type = rettype # jvmtype
+
+ # Compute the method descriptior, which is a string like "()I":
+ argtypesdesc = [a.descriptor for a in argtypes]
+ rettypedesc = rettype.descriptor
+ self.descriptor = desc_for_method(argtypesdesc, rettypedesc)
def invoke(self, gen):
gen._instr(self.opcode, self)
def jasmin_syntax(self):
@@ -362,10 +365,11 @@
# Field objects encode information about fields.
class Field(object):
- def __init__(self, classnm, fieldnm, jtype, static):
+ def __init__(self, classnm, fieldnm, jtype, static, OOTYPE=None):
# All fields are public
self.class_name = classnm # String, ie. "java.lang.Math"
self.field_name = fieldnm # String "someField"
+ self.OOTYPE = OOTYPE # OOTYPE equivalent of JvmType, may be None
self.jtype = jtype # JvmType
self.is_static = static # True or False
def load(self, gen):
@@ -450,14 +454,14 @@
# If the name does not begin with '_', it will be called from
# outside the generator.
- def begin_class(self, classty, superclsty):
+ def begin_class(self, classty, superclsty, abstract=False):
"""
Begins a class declaration. Overall flow of class declaration
looks like:
begin_class()
[add_field()]
- emit_constructor()
+ begin_constructor()...end_constructor()
[begin_function()...end_function()]
end_class()
@@ -468,14 +472,14 @@
"""
assert not self.curclass
self.curclass = ClassState(classty, superclsty)
- self._begin_class()
+ self._begin_class(abstract)
def end_class(self):
self._end_class()
self.curclass = None
self.curfunc = None
- def _begin_class(self):
+ def _begin_class(self, abstract):
""" Main implementation of begin_class """
raise NotImplementedError
@@ -489,7 +493,7 @@
"""
unimplemented
- def emit_constructor(self):
+ def begin_constructor(self):
"""
Emits the constructor for this class, which merely invokes the
parent constructor.
@@ -498,14 +502,16 @@
"""
self.begin_function("", [], [self.curclass.class_type], jVoid)
self.load_jvm_var(self.curclass.class_type, 0)
- jmethod = Method(self.curclass.superclass_type.name, "", "()V",
- opcode=INVOKESPECIAL)
+ jmethod = Method(self.curclass.superclass_type.name, "",
+ (), jVoid, opcode=INVOKESPECIAL)
jmethod.invoke(self)
+
+ def end_constructor(self):
self.return_val(jVoid)
self.end_function()
def begin_function(self, funcname, argvars, argtypes, rettype,
- static=False):
+ static=False, abstract=False):
"""
funcname --- name of the function
argvars --- list of objects passed to load() that represent arguments;
@@ -529,9 +535,9 @@
# Prepare a map for the local variable indices we will add
# Let the subclass do the rest of the work; note that it does
# not need to know the argvars parameter, so don't pass it
- self._begin_function(funcname, argtypes, rettype, static)
+ self._begin_function(funcname, argtypes, rettype, static, abstract)
- def _begin_function(self, funcname, argtypes, rettype, static):
+ def _begin_function(self, funcname, argtypes, rettype, static, abstract):
"""
Main implementation of begin_function. The begin_function()
does some generic handling of args.
@@ -792,7 +798,7 @@
def new(self, TYPE):
jtype = self.db.lltype_to_cts(TYPE)
- ctor = Method(jtype.name, "", "()V", opcode=INVOKESPECIAL)
+ ctor = Method(jtype.name, "", (), jVoid, opcode=INVOKESPECIAL)
self.emit(NEW, jtype)
self.emit(DUP)
self.emit(ctor)
@@ -978,7 +984,7 @@
JVMGenerator.__init__(self, db)
self.outdir = outdir
- def _begin_class(self):
+ def _begin_class(self, abstract):
"""
classnm --- full Java name of the class (i.e., "java.lang.String")
"""
@@ -996,7 +1002,9 @@
self.db.add_jasmin_file(jfile)
# Write the JasminXT header
- self.curclass.out(".class public %s\n" % iclassnm)
+ fields = ["public"]
+ if abstract: fields.append('abstract')
+ self.curclass.out(".class %s %s\n" % (" ".join(fields), iclassnm))
self.curclass.out(".super %s\n" % isuper)
def _end_class(self):
@@ -1014,22 +1022,25 @@
self.curclass.out('.field %s %s %s\n' % (
" ".join(kw), fobj.field_name, fobj.jtype.descriptor))
- def _begin_function(self, funcname, argtypes, rettype, static):
+ def _begin_function(self, funcname, argtypes, rettype, static, abstract):
if not static: argtypes = argtypes[1:]
# Throws clause? Only use RuntimeExceptions?
kw = ['public']
if static: kw.append('static')
+ if abstract: kw.append('abstract')
self.curclass.out('.method %s %s(%s)%s\n' % (
" ".join(kw),
funcname,
"".join([a.descriptor for a in argtypes]),
rettype.descriptor))
+ self._abstract_method = abstract
def _end_function(self):
- self.curclass.out('.limit stack 100\n') # HACK, track max offset
- self.curclass.out('.limit locals %d\n' % self.curfunc.next_offset)
+ if not self._abstract_method:
+ self.curclass.out('.limit stack 100\n') # HACK, track max offset
+ self.curclass.out('.limit locals %d\n' % self.curfunc.next_offset)
self.curclass.out('.end method\n')
def mark(self, lbl):
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Tue Jan 9 16:53:38 2007
@@ -22,6 +22,7 @@
from pypy.translator.jvm.opcodes import opcodes
from pypy.translator.jvm.option import getoption
from pypy.translator.oosupport.function import Function as OOFunction
+from pypy.translator.oosupport.constant import push_constant
import pypy.translator.jvm.generator as jvmgen
class Node(object):
@@ -237,33 +238,40 @@
""" Represents a class to be emitted. Note that currently, classes
are emitted all in one shot, not piecemeal. """
- def __init__(self, name, supercls):
+ def __init__(self, name, supercls=None):
"""
'name' should be a fully qualified Java class name like
"java.lang.String", supercls is a Class object
"""
JvmClassType.__init__(self, name)
- self.super_class = supercls
+ self.super_class = supercls # can also be set later with set_super_class
self.fields = {}
self.rendered = False
+ self.abstract = False
self.methods = {}
+ self.abstract_methods = {}
+
+ def set_super_class(self, supercls):
+ self.super_class = supercls
- def add_field(self, fieldobj):
+ def add_field(self, fieldobj, fielddef):
""" Creates a new field accessed via the jvmgen.Field
descriptor 'fieldobj'. Must be called before render()."""
assert not self.rendered and isinstance(fieldobj, jvmgen.Field)
- self.fields[fieldobj.field_name] = fieldobj
+ self.fields[fieldobj.field_name] = (fieldobj, fielddef)
def lookup_field(self, fieldnm):
""" Given a field name, returns a jvmgen.Field object """
if fieldnm in self.fields:
- return self.fields[fieldnm]
+ return self.fields[fieldnm][0]
return self.super_class.lookup_field(fieldnm)
def lookup_method(self, methodnm):
""" Given the method name, returns a jvmgen.Method object """
if methodnm in self.methods:
return self.methods[methodnm].method()
+ if methodnm in self.abstract_methods:
+ return self.abstract_methods[methodnm]
return self.super_class.lookup_method(methodnm)
def add_method(self, func):
@@ -273,21 +281,43 @@
'methods' may actually represent static functions. """
self.methods[func.name] = func
+ def add_abstract_method(self, jmethod):
+ """ Adds an abstract method to our list of methods; jmethod should
+ be a jvmgen.Method object """
+ assert jmethod.method_name not in self.methods
+ self.abstract = True
+ self.abstract_methods[jmethod.method_name] = jmethod
+
def add_dump_method(self, dm):
self.dump_method = dm # public attribute for reading
self.add_method(dm)
def render(self, gen):
self.rendered = True
- gen.begin_class(self, self.super_class)
+ gen.begin_class(self, self.super_class, abstract=self.abstract)
- for field in self.fields.values():
+ for field, fielddef in self.fields.values():
gen.add_field(field)
- gen.emit_constructor()
+ # Emit the constructor:
+ gen.begin_constructor()
+ # set default values for fields
+ for field, f_default in self.fields.values():
+ if field.jtype is not jVoid:
+ gen.load_jvm_var(self, 0) # load this ptr
+ # load default value of field
+ push_constant(gen.db, field.OOTYPE, f_default, gen)
+ field.store(gen) # store value into field
+ gen.end_constructor()
for method in self.methods.values():
method.render(gen)
+
+ for method in self.abstract_methods.values():
+ gen.begin_function(
+ method.method_name, None, method.argument_types,
+ method.return_type, abstract=True)
+ gen.end_function()
gen.end_class()
From santagada at codespeak.net Tue Jan 9 17:13:20 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Tue, 9 Jan 2007 17:13:20 +0100 (CET)
Subject: [pypy-svn] r36374 - pypy/dist/pypy/lang/js
Message-ID: <20070109161320.683901007E@code0.codespeak.net>
Author: santagada
Date: Tue Jan 9 17:13:18 2007
New Revision: 36374
Added:
pypy/dist/pypy/lang/js/autopath.py
- copied unchanged from r36358, pypy/dist/pypy/bin/autopath.py
pypy/dist/pypy/lang/js/js_interactive.py (contents, props changed)
Modified:
pypy/dist/pypy/lang/js/jsobj.py
Log:
new interactive interepreter
Added: pypy/dist/pypy/lang/js/js_interactive.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lang/js/js_interactive.py Tue Jan 9 17:13:18 2007
@@ -0,0 +1,60 @@
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+js_interactive.py
+"""
+
+import autopath
+import sys
+import getopt
+from pypy.lang.js.interpreter import *
+from pypy.lang.js.jsobj import W_Builtin
+
+help_message = '''
+The help message goes here.
+'''
+
+
+class Usage(Exception):
+ def __init__(self, msg):
+ self.msg = msg
+
+
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv
+ try:
+ try:
+ opts, args = getopt.getopt(argv[1:], "ho:v", ["help", "output="])
+ except getopt.error, msg:
+ raise Usage(msg)
+
+ # option processing
+ for option, value in opts:
+ if option == "-v":
+ verbose = True
+ if option in ("-h", "--help"):
+ raise Usage(help_message)
+ if option in ("-o", "--output"):
+ output = value
+
+ except Usage, err:
+ print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
+ print >> sys.stderr, "\t for help use --help"
+ return 2
+
+ interp = Interpreter()
+ def quiter():
+ sys.exit(0)
+ return "this should not be printed"
+
+ interp.w_Global.Put('quit', W_Builtin(quiter))
+
+ while 1:
+ res = interp.run(load_source(raw_input("pypy-js>")))
+ if res is not None:
+ print res
+
+
+if __name__ == "__main__":
+ sys.exit(main())
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Tue Jan 9 17:13:18 2007
@@ -305,7 +305,7 @@
def Call(self, ctx, args=[], this = None):
assert len(args) == 0
return W_String(self.builtinfunction()) # ???
-
+
class W_List(W_Root):
def __init__(self, list_w):
self.list_w = list_w
From pedronis at codespeak.net Tue Jan 9 18:28:33 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 9 Jan 2007 18:28:33 +0100 (CET)
Subject: [pypy-svn] r36382 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070109172833.AB57810083@code0.codespeak.net>
Author: pedronis
Date: Tue Jan 9 18:28:30 2007
New Revision: 36382
Modified:
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
do the correct thing for virtualizable structs escaping to the outside jit world with setfield or return.
with tests.
(fix some typos in the tests)
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Tue Jan 9 18:28:30 2007
@@ -141,6 +141,12 @@
assert jitstate.resuming is None
returnbox = rtimeshift.getreturnbox(jitstate)
gv_ret = returnbox.getgenvar(jitstate.curbuilder)
+ builder = jitstate.curbuilder
+ for virtualizable_box in jitstate.virtualizables:
+ assert isinstance(virtualizable_box, rvalue.PtrRedBox)
+ content = virtualizable_box.content
+ assert isinstance(content, rcontainer.VirtualizableStruct)
+ content.store_back(builder)
store_global_excdata(jitstate)
jitstate.curbuilder.finish_and_return(graphsigtoken, gv_ret)
self.ll_finish_jitstate = ll_finish_jitstate
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Tue Jan 9 18:28:30 2007
@@ -43,7 +43,7 @@
arrayfielddesc = None
alloctoken = None
varsizealloctoken = None
- materialize = None
+ materialize = None
def __init__(self, RGenOp, TYPE):
self.TYPE = TYPE
@@ -84,6 +84,9 @@
if TYPE._hints.get('virtualizable', False):
self.__class__ = VirtualizableStructTypeDesc
+ self.VStructCls = VirtualizableStruct
+ else:
+ self.VStructCls = VirtualStruct
if self.immutable and self.noidentity:
descs = unrolling_iterable(fielddescs)
@@ -250,6 +253,7 @@
class VirtualStruct(VirtualContainer):
+ typedesc = None
def __init__(self, typedesc):
self.typedesc = typedesc
@@ -257,6 +261,7 @@
#self.ownbox = ... set in factory()
def enter_block(self, incoming, memo):
+ assert self.typedesc is not None
contmemo = memo.containers
if self not in contmemo:
contmemo[self] = None
@@ -265,6 +270,7 @@
def force_runtime_container(self, builder):
typedesc = self.typedesc
+ assert typedesc is not None
boxes = self.content_boxes
self.content_boxes = None
if typedesc.materialize is not None:
@@ -291,21 +297,25 @@
def freeze(self, memo):
contmemo = memo.containers
assert self not in contmemo # contmemo no longer used
+ assert self.typedesc is not None
result = contmemo[self] = FrozenVirtualStruct(self.typedesc)
frozens = [box.freeze(memo) for box in self.content_boxes]
result.fz_content_boxes = frozens
return result
-
+
def copy(self, memo):
+ typedesc = self.typedesc
+ assert typedesc is not None
contmemo = memo.containers
assert self not in contmemo # contmemo no longer used
- result = contmemo[self] = VirtualStruct(self.typedesc)
+ result = contmemo[self] = typedesc.VStructCls(typedesc)
result.content_boxes = [box.copy(memo)
for box in self.content_boxes]
result.ownbox = self.ownbox.copy(memo)
return result
def replace(self, memo):
+ assert self.typedesc is not None
contmemo = memo.containers
assert self not in contmemo # contmemo no longer used
contmemo[self] = None
@@ -326,7 +336,11 @@
class VirtualizableStruct(VirtualStruct):
def force_runtime_container(self, builder):
- assert 0, "not implemented for now"
+ assert 0
+
+ def getgenvar(self):
+ assert self.typedesc is not None
+ return self.content_boxes[-1].genvar
def store_back(self, builder):
fielddescs = self.typedesc.fielddescs
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Tue Jan 9 18:28:30 2007
@@ -274,16 +274,18 @@
if not self.genvar:
content = self.content
from pypy.jit.timeshifter import rcontainer
+ if isinstance(content, rcontainer.VirtualizableStruct):
+ return content.getgenvar()
assert isinstance(content, rcontainer.VirtualContainer)
content.force_runtime_container(builder)
assert self.genvar
return self.genvar
-## def forcevar(self, builder, memo):
-## RedBox.forcevar(self, builder, memo)
-## # if self.content is still there, it's a PartialDataStruct
-## # - for now, we always remove it in this situation
-## self.content = None
+ def forcevar(self, builder, memo):
+ from pypy.jit.timeshifter import rcontainer
+ # xxx
+ assert not isinstance(self.content, rcontainer.VirtualizableStruct)
+ return RedBox.forcevar(self, builder, memo)
def enter_block(self, incoming, memo):
if self.genvar:
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Tue Jan 9 18:28:30 2007
@@ -99,7 +99,7 @@
x = xy.x
xy_access = xy.access
if xy_access:
- xy_access.set_y(xy, 1)
+ xy_access.set_y(xy, 3)
else:
xy.y = 3
xy_access = xy.access
@@ -125,4 +125,67 @@
assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
[lltype.Ptr(XY), lltype.Signed, lltype.Signed])
-
+ def test_simple_explicit_escape(self):
+ E = lltype.GcStruct('e', ('xy', lltype.Ptr(XY)))
+
+ def f(e, xy):
+ xy_access = xy.access
+ if xy_access:
+ xy_access.set_y(xy, 3)
+ else:
+ xy.y = 3
+ e.xy = xy
+ return 0
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ e = lltype.malloc(E)
+ f(e, xy)
+ return e.xy.x+e.xy.y
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 23
+ self.check_insns(getfield=0)
+ residual_graph = self.get_residual_graph()
+ assert len(residual_graph.startblock.inputargs) == 4
+ assert ([v.concretetype for v in residual_graph.startblock.inputargs] ==
+ [lltype.Ptr(E), lltype.Ptr(XY), lltype.Signed, lltype.Signed])
+
+ def test_simple_explicit_return_it(self):
+ def f(which, xy1, xy2):
+ xy1_access = xy1.access
+ if xy1_access:
+ xy1_access.set_y(xy1, 3)
+ else:
+ xy1.y = 3
+ xy2_access = xy2.access
+ if xy2_access:
+ xy2_access.set_y(xy2, 7)
+ else:
+ xy2.y = 7
+ if which == 1:
+ return xy1
+ else:
+ return xy2
+
+ def main(which, x, y):
+ xy1 = lltype.malloc(XY)
+ xy1.access = lltype.nullptr(XY_ACCESS)
+ xy2 = lltype.malloc(XY)
+ xy2.access = lltype.nullptr(XY_ACCESS)
+ xy1.x = x
+ xy1.y = y
+ xy2.x = y
+ xy2.y = x
+ xy = f(which, xy1, xy2)
+ assert xy is xy1 or xy is xy2
+ return xy.x+xy.y
+
+ res = self.timeshift_from_portal(main, f, [1, 20, 22],
+ policy=P_NOVIRTUAL)
+ assert res == 23
+ self.check_insns(getfield=0)
+
From pedronis at codespeak.net Tue Jan 9 18:57:29 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 9 Jan 2007 18:57:29 +0100 (CET)
Subject: [pypy-svn] r36383 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070109175729.AA99810075@code0.codespeak.net>
Author: pedronis
Date: Tue Jan 9 18:57:26 2007
New Revision: 36383
Modified:
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
let virtualizable struct be constructed in timeshifted code, with test.
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Tue Jan 9 18:57:26 2007
@@ -85,6 +85,8 @@
if TYPE._hints.get('virtualizable', False):
self.__class__ = VirtualizableStructTypeDesc
self.VStructCls = VirtualizableStruct
+ outside_null = self.PTRTYPE._defl()
+ self.gv_defl_outside = RGenOp.constPrebuiltGlobal(outside_null)
else:
self.VStructCls = VirtualStruct
@@ -129,8 +131,8 @@
vstruct = VirtualizableStruct(self)
vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
for desc in self.fielddescs]
- outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
- # xxx set outsidebox.genvar
+ outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind,
+ self.gv_defl_outside)
vstruct.content_boxes.append(outsidebox)
box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
box.content = vstruct
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Tue Jan 9 18:57:26 2007
@@ -189,3 +189,28 @@
assert res == 23
self.check_insns(getfield=0)
+ def test_simple_explicit_construct_no_escape(self):
+
+ def f(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ xy_access = xy.access
+ if xy_access:
+ x = xy_access.get_x(xy)
+ else:
+ x = xy.x
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ return x+y
+
+ def main(x, y):
+ return f(x, y)
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=0)
From cfbolz at codespeak.net Tue Jan 9 19:09:03 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 9 Jan 2007 19:09:03 +0100 (CET)
Subject: [pypy-svn] r36384 - pypy/dist/pypy/module/_md5
Message-ID: <20070109180903.6F93410078@code0.codespeak.net>
Author: cfbolz
Date: Tue Jan 9 19:09:02 2007
New Revision: 36384
Removed:
pypy/dist/pypy/module/_md5/
Log:
this _md5 implementation is entirely useless and does not work. removing it.
From cfbolz at codespeak.net Tue Jan 9 19:10:50 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 9 Jan 2007 19:10:50 +0100 (CET)
Subject: [pypy-svn] r36385 - pypy/dist/pypy/module/wraptest
Message-ID: <20070109181050.2368C10078@code0.codespeak.net>
Author: cfbolz
Date: Tue Jan 9 19:10:44 2007
New Revision: 36385
Removed:
pypy/dist/pypy/module/wraptest/
Log:
this directory is a test disguised as a module. removing it to not be confusing
for myself.
From cfbolz at codespeak.net Tue Jan 9 19:18:36 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Tue, 9 Jan 2007 19:18:36 +0100 (CET)
Subject: [pypy-svn] r36388 - pypy/dist/pypy/config
Message-ID: <20070109181836.CD70F1007E@code0.codespeak.net>
Author: cfbolz
Date: Tue Jan 9 19:18:36 2007
New Revision: 36388
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
add an --allworkingmodules option. remove the --no-faassen option as well as
the --withoutmod-... options for essential modules.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Tue Jan 9 19:18:36 2007
@@ -7,11 +7,24 @@
all_modules = [p.basename for p in modulepath.listdir()
if p.check(dir=True, dotfile=False)]
-default_modules = dict.fromkeys(
- [#"unicodedata",
- "_codecs", "gc", "_weakref", "array", "marshal", "errno",
- "math", "_sre", "_pickle_support", "sys", "exceptions", "__builtins__",
- "recparser", "symbol", "_random", "_file", "pypymagic"])
+essential_modules = dict.fromkeys(
+ ["exceptions", "_file", "sys", "__builtin__", "posix"]
+)
+
+default_modules = essential_modules.copy()
+default_modules.update(dict.fromkeys(
+ ["_codecs", "gc", "_weakref", "array", "marshal", "errno",
+ "math", "_sre", "_pickle_support", "signal",
+ "recparser", "symbol", "_random", "pypymagic"]))
+
+
+working_modules = default_modules.copy()
+working_modules.update(dict.fromkeys(
+ ["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", "bz2",
+ "crypt",
+ ]
+))
+
module_dependencies = { }
if os.name == "posix":
@@ -56,9 +69,18 @@
BoolOption(modname, "use module %s" % (modname, ),
default=modname in default_modules,
cmdline="--withmod-%s" % (modname, ),
- requires= module_dependencies.get(modname, []))
+ requires=module_dependencies.get(modname, []),
+ negation=modname not in essential_modules)
for modname in all_modules]),
+ BoolOption("allworkingmodules", "use as many working modules as possible",
+ default=False,
+ cmdline="--allworkingmodules",
+ requires=[("objspace.usemodules.%s" % (modname, ), True)
+ for modname in working_modules
+ if modname in all_modules],
+ negation=False),
+
BoolOption("geninterp", "specify whether geninterp should be used",
default=True),
@@ -139,7 +161,7 @@
("objspace.std.withrangelist", True),
("objspace.std.optimized_int_add", True),
],
- cmdline="--faassen"),
+ cmdline="--faassen", negation=False),
BoolOption("llvmallopts",
"enable all optimizations, and use llvm compiled via C",
@@ -147,7 +169,7 @@
requires=[("objspace.std.allopts", True),
("translation.llvm_via_c", True),
("translation.backend", "llvm")],
- cmdline="--llvm-faassen"),
+ cmdline="--llvm-faassen", negation=False),
]),
BoolOption("lowmem", "Try to use little memory during translation",
default=False, cmdline="--lowmem",
From pedronis at codespeak.net Tue Jan 9 19:21:08 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Tue, 9 Jan 2007 19:21:08 +0100 (CET)
Subject: [pypy-svn] r36389 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070109182108.162E71007A@code0.codespeak.net>
Author: pedronis
Date: Tue Jan 9 19:21:06 2007
New Revision: 36389
Modified:
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
intermediate check-in with wip test about virtualized struct allocated in the timeshifted code and escaping back to
the outside world.
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Tue Jan 9 19:21:06 2007
@@ -340,9 +340,15 @@
def force_runtime_container(self, builder):
assert 0
- def getgenvar(self):
- assert self.typedesc is not None
- return self.content_boxes[-1].genvar
+ def getgenvar(self, builder):
+ typedesc = self.typedesc
+ assert typedesc is not None
+ gv_outside = self.content_boxes[-1].genvar
+ if gv_outside is typedesc.gv_defl_outside:
+ gv_outside = builder.genop_malloc_fixedsize(typedesc.alloctoken)
+ self.content_boxes[-1].genvar = gv_outside
+ # xxx jitstate please
+ return gv_outside
def store_back(self, builder):
fielddescs = self.typedesc.fielddescs
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Tue Jan 9 19:21:06 2007
@@ -275,7 +275,7 @@
content = self.content
from pypy.jit.timeshifter import rcontainer
if isinstance(content, rcontainer.VirtualizableStruct):
- return content.getgenvar()
+ return content.getgenvar(builder)
assert isinstance(content, rcontainer.VirtualContainer)
content.force_runtime_container(builder)
assert self.genvar
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Tue Jan 9 19:21:06 2007
@@ -214,3 +214,31 @@
res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
assert res == 42
self.check_insns(getfield=0)
+
+ def test_simple_explicit_construct_escape(self):
+ py.test.skip("in-progress")
+
+ def f(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ xy_access = xy.access
+ if xy_access:
+ x = xy_access.get_x(xy)
+ else:
+ x = xy.x
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ return xy
+
+ def main(x, y):
+ xy = f(x, y)
+ return xy.x+xy.y
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=0)
From mwh at codespeak.net Wed Jan 10 00:12:49 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Wed, 10 Jan 2007 00:12:49 +0100 (CET)
Subject: [pypy-svn] r36392 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070109231249.C621710075@code0.codespeak.net>
Author: mwh
Date: Wed Jan 10 00:12:37 2007
New Revision: 36392
Modified:
pypy/dist/pypy/jit/codegen/ppc/codebuf.py
pypy/dist/pypy/jit/codegen/ppc/conftest.py
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
(mwh, a little arigo)
After only moderately crazy amounts of head-bashing, get the ppc jit tests
running again.
Modified: pypy/dist/pypy/jit/codegen/ppc/codebuf.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/codebuf.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/codebuf.py Wed Jan 10 00:12:37 2007
@@ -55,11 +55,11 @@
self._pos = _pos
def write(self, data):
- p = self._pos
- if p >= self._size:
- raise CodeBlockOverflow
- self._data.contents[p] = data
- self._pos = p + 1
+ p = self._pos
+ if p >= self._size:
+ raise CodeBlockOverflow
+ self._data.contents[p] = data
+ self._pos = p + 1
def getpos(self):
return self._pos
@@ -77,6 +77,13 @@
self.write(0)
return r
+class ExistingCodeBlock(MachineCodeBlock):
+ def __init__(self, start, end):
+ self._size = (end-start)/4
+ p = c_void_p(start)
+ self._data = cast(p, POINTER(c_int * self._size))
+ self._pos = 0
+
class OwningMachineCodeBlock(MachineCodeBlock):
def __del__(self):
free(cast(self._data, PTR), self._size * 4)
Modified: pypy/dist/pypy/jit/codegen/ppc/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/conftest.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/conftest.py Wed Jan 10 00:12:37 2007
@@ -5,7 +5,6 @@
class Directory(py.test.collect.Directory):
def run(self):
- import py; py.test.skip("in-progress")
try:
processor = detect_cpu.autodetect()
except detect_cpu.ProcessorAutodetectError, e:
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Wed Jan 10 00:12:37 2007
@@ -78,10 +78,10 @@
reg_arg_regclasses is the type of register that needs to be allocated
'''
def __init__(self):
- self.__magic_index = _insn_index[0]
+ self._magic_index = _insn_index[0]
_insn_index[0] += 1
def __repr__(self):
- return "<%s %d>" % (self.__class__.__name__, self.__magic_index)
+ return "<%s %d>" % (self.__class__.__name__, self._magic_index)
class Insn_GPR__GPR_GPR(Insn):
def __init__(self, methptr, result, args):
@@ -98,6 +98,9 @@
self.arg_reg1 = allocator.loc_of(self.reg_args[0])
self.arg_reg2 = allocator.loc_of(self.reg_args[1])
+ def __repr__(self):
+ return "<%s %s %d>" % (self.__class__.__name__, self.methptr.im_func.func_name, self._magic_index)
+
def emit(self, asm):
self.methptr(asm,
self.result_reg.number,
@@ -117,6 +120,9 @@
def allocate(self, allocator):
self.result_reg = allocator.loc_of(self.result)
self.arg_reg = allocator.loc_of(self.reg_args[0])
+ def __repr__(self):
+ return "<%s %s %d>" % (self.__class__.__name__, self.methptr.im_func.func_name, self._magic_index)
+
def emit(self, asm):
self.methptr(asm,
self.result_reg.number,
@@ -135,6 +141,9 @@
def allocate(self, allocator):
self.result_reg = allocator.loc_of(self.result)
self.arg_reg = allocator.loc_of(self.reg_args[0])
+ def __repr__(self):
+ return "<%s %s %d>" % (self.__class__.__name__, self.methptr.im_func.func_name, self._magic_index)
+
def emit(self, asm):
self.methptr(asm,
self.result_reg.number,
@@ -152,6 +161,9 @@
self.reg_arg_regclasses = []
def allocate(self, allocator):
self.result_reg = allocator.loc_of(self.result)
+ def __repr__(self):
+ return "<%s %s %d>" % (self.__class__.__name__, self.methptr.im_func.func_name, self._magic_index)
+
def emit(self, asm):
self.methptr(asm,
self.result_reg.number,
@@ -170,6 +182,9 @@
def allocate(self, allocator):
self.reg1 = allocator.loc_of(self.reg_args[0])
self.reg2 = allocator.loc_of(self.reg_args[1])
+ def __repr__(self):
+ return "<%s %s %d>" % (self.__class__.__name__, self.methptr.im_func.func_name, self._magic_index)
+
def emit(self, asm):
self.methptr(asm,
self.reg1.number,
@@ -189,6 +204,9 @@
self.reg1 = allocator.loc_of(self.reg_args[0])
self.reg2 = allocator.loc_of(self.reg_args[1])
self.reg3 = allocator.loc_of(self.reg_args[2])
+ def __repr__(self):
+ return "<%s %s %d>" % (self.__class__.__name__, self.methptr.im_func.func_name, self._magic_index)
+
def emit(self, asm):
self.methptr(asm,
self.reg1.number,
@@ -253,21 +271,33 @@
## asm.mtctr(self.arg_reg.number)
class Jump(Insn):
- def __init__(self, gv_cond, gv_target, jump_if_true):
+ def __init__(self, gv_cond, targetbuilder, jump_if_true, jump_args_gv):
Insn.__init__(self)
self.gv_cond = gv_cond
- self.gv_target = gv_target
self.jump_if_true = jump_if_true
self.result = None
self.result_regclass = NO_REGISTER
- self.reg_args = [gv_cond, gv_target]
- self.reg_arg_regclasses = [CR_FIELD, CT_REGISTER]
+ self.reg_args = [gv_cond]
+ self.reg_arg_regclasses = [CR_FIELD]
+
+ self.jump_args_gv = jump_args_gv
+ self.targetbuilder = targetbuilder
def allocate(self, allocator):
- assert allocator.loc_of(self.reg_args[1]) is ctr
self.crf = allocator.loc_of(self.reg_args[0])
self.bit, self.negated = allocator.crfinfo[self.crf.number]
+
+ self.targetbuilder.initial_var2loc = {}
+ for gv_arg in self.jump_args_gv:
+ self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
+ self.targetbuilder.initial_spill_offset = allocator.spill_offset
def emit(self, asm):
+ if self.targetbuilder.start:
+ asm.load_word(rSCRATCH, self.targetbuilder.start)
+ else:
+ self.targetbuilder.patch_start_here = asm.mc.tell()
+ asm.load_word(rSCRATCH, 0)
+ asm.mtctr(rSCRATCH)
if self.negated ^ self.jump_if_true:
BO = 12 # jump if relavent bit is set in the CR
else:
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Wed Jan 10 00:12:37 2007
@@ -182,16 +182,20 @@
class Builder(GenBuilder):
- def __init__(self, rgenop, mc):
+ def __init__(self, rgenop):
self.rgenop = rgenop
self.asm = RPPCAssembler()
- self.asm.mc = mc
+ self.asm.mc = None
self.insns = []
self.stack_adj_addr = 0
self.initial_spill_offset = 0
self.initial_var2loc = None
- self.fresh_from_jump = False
self.max_param_space = -1
+ self.final_jump_addr = 0
+
+ self.start = 0
+ self.closed = True
+ self.patch_start_here = 0
# ----------------------------------------------------------------
# the public Builder interface:
@@ -318,11 +322,8 @@
## def genop_debug_pdb(self): # may take an args_gv later
def enter_next_block(self, kinds, args_gv):
- if self.fresh_from_jump:
- var2loc = self.initial_var2loc
- self.fresh_from_jump = False
- else:
- var2loc = self.allocate_and_emit().var2loc
+ vars_gv = [v for v in args_gv if isinstance(v, Var)]
+ var2loc = self.allocate_and_emit(vars_gv).var2loc
#print "enter_next_block:", args_gv, var2loc
@@ -366,15 +367,15 @@
self.emit_stack_adjustment()
return Label(target_addr, arg_locations, min_stack_offset)
- def jump_if_false(self, gv_condition):
- return self._jump(gv_condition, False)
+ def jump_if_false(self, gv_condition, args_gv):
+ return self._jump(gv_condition, False, args_gv)
- def jump_if_true(self, gv_condition):
- return self._jump(gv_condition, True)
+ def jump_if_true(self, gv_condition, args_gv):
+ return self._jump(gv_condition, True, args_gv)
def finish_and_return(self, sigtoken, gv_returnvar):
self.insns.append(insn.Return(gv_returnvar))
- self.allocate_and_emit()
+ self.allocate_and_emit([])
# standard epilogue:
@@ -393,7 +394,7 @@
self._close()
def finish_and_goto(self, outputargs_gv, target):
- allocator = self.allocate_and_emit()
+ allocator = self.allocate_and_emit(outputargs_gv)
min_offset = min(allocator.spill_offset, target.min_stack_offset)
min_offset = prepare_for_jump(
self.asm, min_offset, outputargs_gv, allocator.var2loc, target)
@@ -403,17 +404,54 @@
self.asm.bctr()
self._close()
- def flexswitch(self, gv_exitswitch):
+ def flexswitch(self, gv_exitswitch, args_gv):
# make sure the exitswitch ends the block in a register:
crresult = Var()
self.insns.append(insn.FakeUse(crresult, gv_exitswitch))
- allocator = self.allocate_and_emit()
+ allocator = self.allocate_and_emit(args_gv)
switch_mc = self.asm.mc.reserve(7 * 5 + 4)
self._close()
- return FlexSwitch(self.rgenop, switch_mc,
- allocator.loc_of(gv_exitswitch),
- allocator.loc_of(crresult),
- allocator.var2loc)
+ result = FlexSwitch(self.rgenop, switch_mc,
+ allocator.loc_of(gv_exitswitch),
+ allocator.loc_of(crresult),
+ allocator.var2loc)
+ return result, result.add_default()
+
+ def start_writing(self):
+ if not self.closed:
+ return self
+ assert self.asm.mc is None
+ if self.final_jump_addr != 0:
+ mc = self.rgenop.open_mc()
+ target = mc.tell()
+ self.asm.mc = codebuf.ExistingCodeBlock(self.final_jump_addr, self.final_jump_addr+8)
+ self.asm.load_word(rSCRATCH, target)
+ self.asm.mc = mc
+ self.emit_stack_adjustment()
+ return self
+ else:
+ self._open()
+ self.maybe_patch_start_here()
+ self.emit_stack_adjustment()
+ return self
+
+ def maybe_patch_start_here(self):
+ if self.patch_start_here:
+ mc = self.asm.mc
+ self.asm.mc = codebuf.ExistingCodeBlock(self.patch_start_here, self.patch_start_here+8)
+ self.asm.load_word(rSCRATCH, mc.tell())
+ self.asm.mc = mc
+ self.patch_start_here = 0
+
+ def pause_writing(self, args_gv):
+ self.allocate_and_emit(args_gv)
+ self.final_jump_addr = self.asm.mc.tell()
+ self.asm.nop()
+ self.asm.nop()
+ self.asm.mtctr(rSCRATCH)
+ self.asm.bctr()
+ self._close()
+ return self
# ----------------------------------------------------------------
# ppc-specific interface:
@@ -432,11 +470,6 @@
gv_itemoffset, [gv_offset, IntConst(startoffset)]))
return gv_itemoffset
- def make_fresh_from_jump(self, initial_var2loc):
- self.fresh_from_jump = True
- self.initial_var2loc = initial_var2loc
- self.max_param_space = -1
-
def _write_prologue(self, sigtoken):
numargs = sigtoken # for now
if DEBUG_TRAP:
@@ -494,11 +527,14 @@
param = 0
return ((4 + param - lv + 15) & ~15)
+ def _open(self):
+ self.asm.mc = self.rgenop.open_mc()
+
def _close(self):
self.rgenop.close_mc(self.asm.mc)
self.asm.mc = None
- def allocate_and_emit(self):
+ def allocate_and_emit(self, live_vars_gv):
assert self.initial_var2loc is not None
allocator = RegisterAllocation(
self.rgenop.freeregs, self.initial_var2loc, self.initial_spill_offset)
@@ -523,6 +559,7 @@
# note that this stomps on both rSCRATCH (not a problem) and
# crf0 (a very small chance of being a problem)
self.stack_adj_addr = self.asm.mc.tell()
+ #print "emit_stack_adjustment at: ", self.stack_adj_addr
self.asm.addi(rSCRATCH, rFP, 0) # this is the immediate that later gets patched
self.asm.subx(rSCRATCH, rSCRATCH, rSP) # rSCRATCH should now be <= 0
self.asm.beq(3) # if rSCRATCH == 0, there is no actual adjustment, so
@@ -534,6 +571,7 @@
def patch_stack_adjustment(self, newsize):
if self.stack_adj_addr == 0:
return
+ #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
# we build an addi instruction by hand here
opcode = 14 << 26
rD = rSCRATCH << 21
@@ -633,17 +671,11 @@
def op_int_ne(self, gv_x, gv_y):
return self._compare('ne', gv_x, gv_y)
- def _jump(self, gv_condition, if_true):
- targetbuilder = self.rgenop.openbuilder()
-
- targetaddr = targetbuilder.asm.mc.tell()
+ def _jump(self, gv_condition, if_true, args_gv):
+ targetbuilder = self.rgenop.newbuilder()
self.insns.append(
- insn.Jump(gv_condition, self.rgenop.genconst(targetaddr), if_true))
-
- allocator = self.allocate_and_emit()
- self.make_fresh_from_jump(allocator.var2loc)
- targetbuilder.make_fresh_from_jump(allocator.var2loc)
+ insn.Jump(gv_condition, targetbuilder, if_true, args_gv))
return targetbuilder
@@ -688,7 +720,8 @@
def newgraph(self, sigtoken, name):
numargs = sigtoken # for now
- builder = self.openbuilder()
+ builder = self.newbuilder()
+ builder._open()
entrypoint = builder.asm.mc.tell()
inputargs_gv = builder._write_prologue(sigtoken)
return builder, IntConst(entrypoint), inputargs_gv
@@ -780,8 +813,8 @@
## mc._size*4)
self.mcs.append(mc)
- def openbuilder(self):
- return Builder(self, self.open_mc())
+ def newbuilder(self):
+ return Builder(self)
# a switch can take 7 instructions:
@@ -808,8 +841,9 @@
self.default_target_addr = 0
def add_case(self, gv_case):
- targetbuilder = self.rgenop.openbuilder()
- targetbuilder.make_fresh_from_jump(self.var2loc)
+ targetbuilder = self.rgenop.newbuilder()
+ targetbuilder._open()
+ targetbuilder.initial_var2loc = self.var2loc
target_addr = targetbuilder.asm.mc.tell()
p = self.asm.mc.getpos()
# that this works depends a bit on the fixed length of the
@@ -843,8 +877,9 @@
self._write_default()
def add_default(self):
- targetbuilder = self.rgenop.openbuilder()
- targetbuilder.make_fresh_from_jump(self.var2loc)
+ targetbuilder = self.rgenop.newbuilder()
+ targetbuilder._open()
+ targetbuilder.initial_var2loc = self.var2loc
self.default_target_addr = targetbuilder.asm.mc.tell()
self._write_default()
return targetbuilder
From niko at codespeak.net Wed Jan 10 00:31:32 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Wed, 10 Jan 2007 00:31:32 +0100 (CET)
Subject: [pypy-svn] r36393 - in pypy/dist/pypy/translator: cli jvm jvm/src
oosupport
Message-ID: <20070109233132.D13A110075@code0.codespeak.net>
Author: niko
Date: Wed Jan 10 00:31:30 2007
New Revision: 36393
Added:
pypy/dist/pypy/translator/jvm/metavm.py
Modified:
pypy/dist/pypy/translator/cli/metavm.py
pypy/dist/pypy/translator/cli/opcodes.py
pypy/dist/pypy/translator/jvm/constant.py
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/genjvm.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/opcodes.py
pypy/dist/pypy/translator/jvm/src/PyPy.java
pypy/dist/pypy/translator/oosupport/constant.py
pypy/dist/pypy/translator/oosupport/metavm.py
Log:
(niko, antocuni)
fix all of test_class.py for the jvm backend
Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py (original)
+++ pypy/dist/pypy/translator/cli/metavm.py Wed Jan 10 00:31:30 2007
@@ -103,13 +103,6 @@
generator.call_signature('object [pypylib]pypy.runtime.Utils::RuntimeNew(class [mscorlib]System.Type)')
generator.cast_to(op.result.concretetype)
-class _CastTo(MicroInstruction):
- def render(self, generator, op):
- generator.load(op.args[0])
- INSTANCE = op.args[1].value
- class_name = generator.db.pending_class(INSTANCE)
- generator.isinstance(class_name)
-
class _OOString(MicroInstruction):
def render(self, generator, op):
ARGTYPE = op.args[0].concretetype
@@ -250,7 +243,6 @@
CallMethod = _CallMethod()
IndirectCall = _IndirectCall()
RuntimeNew = _RuntimeNew()
-CastTo = _CastTo()
OOString = _OOString()
NewCustomDict = _NewCustomDict()
CastWeakAdrToPtr = _CastWeakAdrToPtr()
Modified: pypy/dist/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/cli/opcodes.py (original)
+++ pypy/dist/pypy/translator/cli/opcodes.py Wed Jan 10 00:31:30 2007
@@ -1,9 +1,9 @@
from pypy.translator.cli.metavm import Call, CallMethod, \
- IndirectCall, GetField, SetField, CastTo, OOString, DownCast, NewCustomDict,\
+ IndirectCall, GetField, SetField, OOString, DownCast, NewCustomDict,\
CastWeakAdrToPtr, MapException, Box, Unbox, NewArray, GetArrayElem, SetArrayElem,\
TypeOf
from pypy.translator.oosupport.metavm import PushArg, PushAllArgs, StoreResult, InstructionList,\
- New, RuntimeNew
+ New, RuntimeNew, CastTo
from pypy.translator.cli.cts import WEAKREF
# some useful instruction patterns
Modified: pypy/dist/pypy/translator/jvm/constant.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/constant.py (original)
+++ pypy/dist/pypy/translator/jvm/constant.py Wed Jan 10 00:31:30 2007
@@ -1,7 +1,9 @@
+from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.generator import \
Field, Method
from pypy.translator.oosupport.constant import \
- BaseConstantGenerator, RecordConst, InstanceConst, ClassConst
+ BaseConstantGenerator, RecordConst, InstanceConst, ClassConst, \
+ StaticMethodConst
from pypy.translator.jvm.typesystem import \
jPyPyConst, jObject, jVoid
@@ -54,3 +56,21 @@
gen.end_class()
+class JVMStaticMethodConst(StaticMethodConst):
+
+ def record_dependencies(self):
+ if self.value is ootype.null(self.value._TYPE):
+ self.delegate_impl = None
+ return
+ StaticMethodConst.record_dependencies(self)
+ self.delegate_impl = self.db.record_delegate_impl(self.value.graph)
+
+ def create_pointer(self, gen):
+ if self.delegate_impl:
+ gen.new_with_jtype(self.delegate_impl)
+ else:
+ gen.push_null(jObject)
+
+ def initialize_data(self, ilasm):
+ return
+
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Wed Jan 10 00:31:30 2007
@@ -31,6 +31,9 @@
# and JvmType objects as well
self._functions = {} # graph -> jvmgen.Method
+ # (jargtypes, jrettype) -> node.StaticMethodInterface
+ self._delegates = {}
+
self._function_names = {} # graph --> function_name
self._constants = {} # flowmodel.Variable --> jvmgen.Const
@@ -72,6 +75,14 @@
# Node Creation
#
# Creates nodes that represents classes, functions, simple constants.
+
+ def _types_for_graph(self, graph):
+ argtypes = [arg.concretetype for arg in graph.getargs()
+ if arg.concretetype is not ootype.Void]
+ jargtypes = tuple([self.lltype_to_cts(argty) for argty in argtypes])
+ rettype = graph.getreturnvar().concretetype
+ jrettype = self.lltype_to_cts(rettype)
+ return jargtypes, jrettype
def _function_for_graph(self, classobj, funcnm, is_static, graph):
@@ -79,15 +90,34 @@
Creates a node.Function object for a particular graph. Adds
the method to 'classobj', which should be a node.Class object.
"""
- argtypes = [arg.concretetype for arg in graph.getargs()
- if arg.concretetype is not ootype.Void]
- jargtypes = [self.lltype_to_cts(argty) for argty in argtypes]
- rettype = graph.getreturnvar().concretetype
- jrettype = self.lltype_to_cts(rettype)
+ jargtypes, jrettype = self._types_for_graph(graph)
funcobj = node.Function(
self, classobj, funcnm, jargtypes, jrettype, graph, is_static)
return funcobj
+ def _translate_record(self, OOTYPE):
+ assert OOTYPE is not ootype.ROOT
+
+ # Create class object if it does not already exist:
+ if OOTYPE in self._classes:
+ return self._classes[OOTYPE]
+
+ # Create the class object first
+ clsnm = self._pkg(self._uniq('Record'))
+ clsobj = node.Class(clsnm, jObject)
+ self._classes[OOTYPE] = clsobj
+
+ # Add fields:
+ self._translate_class_fields(clsobj, OOTYPE)
+
+ # TODO --- generate equals/hash methods here
+
+ dump_method = node.RecordDumpMethod(self, OOTYPE, clsobj)
+ clsobj.add_dump_method(dump_method)
+
+ self.pending_node(clsobj)
+ return clsobj
+
def _translate_instance(self, OOTYPE):
assert isinstance(OOTYPE, ootype.Instance)
assert OOTYPE is not ootype.ROOT
@@ -111,12 +141,8 @@
# classes?
# Add fields:
- for fieldnm, (FIELDOOTY, fielddef) in OOTYPE._fields.iteritems():
- if FIELDOOTY is ootype.Void: continue
- fieldty = self.lltype_to_cts(FIELDOOTY)
- clsobj.add_field(
- jvmgen.Field(clsnm, fieldnm, fieldty, False, FIELDOOTY),
- fielddef)
+ # Add fields:
+ self._translate_class_fields(clsobj, OOTYPE)
# Add methods:
for mname, mimpl in OOTYPE._methods.iteritems():
@@ -142,12 +168,20 @@
# currently, we always include a special "dump" method for debugging
# purposes
- dump_method = node.TestDumpMethod(self, OOTYPE, clsobj)
+ dump_method = node.InstanceDumpMethod(self, OOTYPE, clsobj)
clsobj.add_dump_method(dump_method)
self.pending_node(clsobj)
return clsobj
+ def _translate_class_fields(self, clsobj, OOTYPE):
+ for fieldnm, (FIELDOOTY, fielddef) in OOTYPE._fields.iteritems():
+ if FIELDOOTY is ootype.Void: continue
+ fieldty = self.lltype_to_cts(FIELDOOTY)
+ clsobj.add_field(
+ jvmgen.Field(clsobj.name, fieldnm, fieldty, False, FIELDOOTY),
+ fielddef)
+
def pending_class(self, OOTYPE):
return self.lltype_to_cts(OOTYPE)
@@ -169,6 +203,38 @@
res = self._functions[graph] = funcobj.method()
return res
+ def record_delegate(self, TYPE):
+ """ TYPE is a StaticMethod """
+
+ # Translate argument/return types into java types, check if
+ # we already have such a delegate:
+ jargs = tuple([self.lltype_to_cts(ARG) for ARG in TYPE.ARGS])
+ jret = self.lltype_to_cts(TYPE.RESULT)
+ key = (jargs, jret)
+ if key in self._delegates:
+ return self._delegates[key]
+
+ # TODO: Make an intelligent name for this interface by
+ # mangling the list of parameters
+ name = self._pkg(self._uniq('Delegate'))
+
+ # Create a new one if we do not:
+ interface = node.StaticMethodInterface(name, TYPE, jargs, jret)
+ self._delegates[key] = interface
+ self.pending_node(interface)
+ return interface
+
+ def record_delegate_impl(self, graph):
+ """ TYPE is a StaticMethod """
+ jargtypes, jrettype = self._types_for_graph(graph)
+ key = (jargtypes, jrettype)
+ assert key in self._delegates
+ pfunc = self.pending_function(graph)
+ implnm = self._pkg(self._uniq(graph.name+'_delegate'))
+ n = node.StaticMethodImplementation(implnm, self._delegates[key], pfunc)
+ self.pending_node(n)
+ return n
+
# _________________________________________________________________
# Type printing functions
#
@@ -185,6 +251,7 @@
ootype.String:jvmgen.PYPYDUMPSTRING,
ootype.StringBuilder:jvmgen.PYPYDUMPOBJECT,
ootype.Void:jvmgen.PYPYDUMPVOID,
+ ootype.Char:jvmgen.PYPYDUMPCHAR
}
def generate_dump_method_for_ootype(self, OOTYPE):
@@ -264,7 +331,7 @@
if isinstance(OOT, ootype.Record):
return self._translate_record(OOT)
if isinstance(OOT, ootype.StaticMethod):
- return XXX
+ return self.record_delegate(OOT)
assert False, "Untranslatable type %s!" % OOT
@@ -273,7 +340,7 @@
#
# These functions are invoked by the code in oosupport, but I
# don't think we need them or use them otherwise.
-
+
def record_function(self, graph, name):
self._function_names[graph] = name
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Wed Jan 10 00:31:30 2007
@@ -325,12 +325,14 @@
self.method_name,
self.descriptor)
+OBJHASHCODE = Method.v(jObject, 'hashCode', (), jInt)
MATHIABS = Method.s(jMath, 'abs', (jInt,), jInt)
MATHLABS = Method.s(jMath, 'abs', (jLong,), jLong)
MATHDABS = Method.s(jMath, 'abs', (jDouble,), jDouble)
MATHFLOOR = Method.s(jMath, 'floor', (jDouble,), jDouble)
PRINTSTREAMPRINTSTR = Method.v(jPrintStream, 'print', (jString,), jVoid)
CLASSFORNAME = Method.s(jClass, 'forName', (jString,), jClass)
+CLASSISASSIGNABLEFROM = Method.v(jClass, 'isAssignableFrom', (jClass,), jBool)
PYPYUINTCMP = Method.s(jPyPy, 'uint_cmp', (jInt,jInt,), jInt)
PYPYULONGCMP = Method.s(jPyPy, 'ulong_cmp', (jLong,jLong), jInt)
PYPYUINTTODOUBLE = Method.s(jPyPy, 'uint_to_double', (jInt,), jDouble)
@@ -345,6 +347,7 @@
PYPYSTRTOCHAR = Method.s(jPyPy, 'str_to_char', (jString,), jChar)
PYPYDUMPINDENTED = Method.s(jPyPy, 'dump_indented', (jInt,jString,), jVoid)
PYPYDUMPINT = Method.s(jPyPy, 'dump_int', (jInt,jInt), jVoid)
+PYPYDUMPCHAR = Method.s(jPyPy, 'dump_char', (jChar,jInt), jVoid)
PYPYDUMPUINT = Method.s(jPyPy, 'dump_uint', (jInt,jInt), jVoid)
PYPYDUMPLONG = Method.s(jPyPy, 'dump_long', (jLong,jInt), jVoid)
PYPYDUMPDOUBLE = Method.s(jPyPy, 'dump_double', (jDouble,jInt), jVoid)
@@ -414,6 +417,7 @@
def __init__(self):
self.next_offset = 0
self.local_vars = {}
+ self.function_arguments = []
self.instr_counter = 0
def add_var(self, jvar, jtype):
""" Adds new entry for variable 'jvar', of java type 'jtype' """
@@ -422,6 +426,7 @@
if jvar:
assert jvar not in self.local_vars # never been added before
self.local_vars[jvar] = idx
+ self.function_arguments.append((jtype, idx))
return idx
def var_offset(self, jvar, jtype):
""" Returns offset for variable 'jvar', of java type 'jtype' """
@@ -479,6 +484,11 @@
self.curclass = None
self.curfunc = None
+ def current_type(self):
+ """ Returns the jvm type we are currently defining. If
+ begin_class() has not been called, returns None. """
+ return self.curclass.class_type
+
def _begin_class(self, abstract):
""" Main implementation of begin_class """
raise NotImplementedError
@@ -500,8 +510,8 @@
superclsnm --- same Java name of super class as from begin_class
"""
- self.begin_function("", [], [self.curclass.class_type], jVoid)
- self.load_jvm_var(self.curclass.class_type, 0)
+ self.begin_function("", [], [self.current_type()], jVoid)
+ self.load_jvm_var(self.current_type(), 0)
jmethod = Method(self.curclass.superclass_type.name, "",
(), jVoid, opcode=INVOKESPECIAL)
jmethod.invoke(self)
@@ -637,6 +647,12 @@
virtual method, not static methods. """
self.load_jvm_var(jObject, 0)
+ def load_function_argument(self, index):
+ """ Convenience method. Loads function argument #index; note that
+ the this pointer is index #0. """
+ jtype, jidx = self.curfunc.function_arguments[index]
+ self.load_jvm_var(jtype, jidx)
+
# __________________________________________________________________
# Exception Handling
@@ -764,6 +780,9 @@
jtype = self.db.lltype_to_cts(TYPE)
self._instr(INSTANCEOF, jtype)
+ def isinstance(self, jtype):
+ self._instr(INSTANCEOF, jtype)
+
def branch_unconditionally(self, target_label):
self.goto(target_label)
@@ -798,6 +817,9 @@
def new(self, TYPE):
jtype = self.db.lltype_to_cts(TYPE)
+ self.new_with_jtype(jtype)
+
+ def new_with_jtype(self, jtype):
ctor = Method(jtype.name, "", (), jVoid, opcode=INVOKESPECIAL)
self.emit(NEW, jtype)
self.emit(DUP)
@@ -921,7 +943,10 @@
self.mark(endlbl)
is_null = lambda self: self._compare_op(IFNULL)
- is_not_null = lambda self: self._compare_op(IFNOTNULL)
+ is_not_null = lambda self: self._compare_op(IFNONNULL)
+
+ ref_is_eq = lambda self: self._compare_op(IF_ACMPEQ)
+ ref_is_neq = lambda self: self._compare_op(IF_ACMPNEQ)
logical_not = lambda self: self._compare_op(IFEQ)
equals_zero = logical_not
@@ -989,7 +1014,7 @@
classnm --- full Java name of the class (i.e., "java.lang.String")
"""
- iclassnm = self.curclass.class_type.descriptor.int_class_name()
+ iclassnm = self.current_type().descriptor.int_class_name()
isuper = self.curclass.superclass_type.descriptor.int_class_name()
jfile = "%s/%s.j" % (self.outdir, iclassnm)
@@ -1055,8 +1080,9 @@
return str(arg)
strargs = [jasmin_syntax(arg) for arg in args]
instr_text = '%s %s' % (jvmstr, " ".join(strargs))
- self.curclass.out(' %-60s ; %d\n' % (
- instr_text, self.curfunc.instr_counter))
+ self.curclass.out(' .line %d\n' % self.curfunc.instr_counter)
+ self.curclass.out(' %-60s\n' % (
+ instr_text,))
self.curfunc.instr_counter+=1
def _try_catch_region(self, excclsty, trystartlbl, tryendlbl, catchlbl):
Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py (original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py Wed Jan 10 00:31:30 2007
@@ -15,7 +15,8 @@
from pypy.translator.jvm.log import log
from pypy.translator.jvm.node import EntryPoint, Function
from pypy.translator.jvm.opcodes import opcodes
-from pypy.translator.jvm.constant import JVMConstantGenerator
+from pypy.translator.jvm.constant import \
+ JVMConstantGenerator, JVMStaticMethodConst
class JvmError(Exception):
""" Indicates an error occurred in JVM backend """
@@ -180,6 +181,7 @@
log = log
ConstantGenerator = JVMConstantGenerator
+ StaticMethodConst = JVMStaticMethodConst
def __init__(self, tmpdir, translator, entrypoint):
"""
Added: pypy/dist/pypy/translator/jvm/metavm.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/metavm.py Wed Jan 10 00:31:30 2007
@@ -0,0 +1,10 @@
+from pypy.translator.oosupport.metavm import MicroInstruction
+
+
+class _IndirectCall(MicroInstruction):
+ def render(self, gen, op):
+ interface = gen.db.lltype_to_cts(op.args[0].concretetype)
+ method = interface.lookup_method('invoke')
+ gen.emit(method)
+IndirectCall = _IndirectCall()
+
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Wed Jan 10 00:31:30 2007
@@ -18,7 +18,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.typesystem import \
JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, jPyPyMain, \
- jObject
+ jObject, JvmType
from pypy.translator.jvm.opcodes import opcodes
from pypy.translator.jvm.option import getoption
from pypy.translator.oosupport.function import Function as OOFunction
@@ -175,6 +175,7 @@
# Determine return type
jrettype = lltype_to_cts(self.graph.getreturnvar().concretetype)
+
self.ilasm.begin_function(
self.name, jargvars, jargtypes, jrettype, static=not self.is_method)
@@ -233,6 +234,92 @@
OOFunction._render_op(self, op)
+class StaticMethodInterface(Node, JvmClassType):
+ """
+ We generate an abstract base class when we need function pointers,
+ which correspond to constants of StaticMethod ootype. We need a
+ different interface for each different set of argument/return
+ types. These abstract base classes look like:
+
+ abstract class Foo {
+ public abstract ReturnType invoke(Arg1, Arg2, ...);
+ }
+
+ """
+ def __init__(self, name, STATIC_METHOD, jargtypes, jrettype):
+ """
+ argtypes: list of JvmTypes
+ rettype: JvmType
+ """
+ JvmClassType.__init__(self, name)
+ self.STATIC_METHOD = STATIC_METHOD
+ assert isinstance(jrettype, JvmType)
+ self.java_argument_types = [self] + list(jargtypes)
+ self.java_return_type = jrettype
+ self.dump_method = ConstantStringDumpMethod(
+ self, "StaticMethodInterface")
+
+ def lookup_field(self, fieldnm):
+ """ Given a field name, returns a jvmgen.Field object """
+ raise KeyError(fieldnm) # no fields
+ def lookup_method(self, methodnm):
+ """ Given the method name, returns a jvmgen.Method object """
+ assert isinstance(self.java_return_type, JvmType)
+ if methodnm == 'invoke':
+ return jvmgen.Method.v(
+ self, 'invoke',
+ self.java_argument_types[1:], self.java_return_type)
+ raise KeyError(methodnm) # only one method
+ def render(self, gen):
+ assert isinstance(self.java_return_type, JvmType)
+ gen.begin_class(self, jObject, abstract=True)
+ gen.begin_constructor()
+ gen.end_constructor()
+ gen.begin_function('invoke', [], self.java_argument_types,
+ self.java_return_type, abstract=True)
+ gen.end_function()
+ gen.end_class()
+
+class StaticMethodImplementation(Node, JvmClassType):
+ """
+ In addition to the StaticMethodInterface, we must generate an
+ implementation for each specific method that is called. These
+ implementation objects look like:
+
+ class Bar extends Foo {
+ public ReturnType invoke(Arg1, Arg2) {
+ return SomeStaticClass.StaticMethod(Arg1, Arg2);
+ }
+ }
+ """
+ def __init__(self, name, interface, impl_method):
+ JvmClassType.__init__(self, name)
+ self.super_class = interface
+ self.impl_method = impl_method
+ self.dump_method = ConstantStringDumpMethod(
+ self, "StaticMethodImplementation")
+ def lookup_field(self, fieldnm):
+ """ Given a field name, returns a jvmgen.Field object """
+ return self.super_class.lookup_field(fieldnm)
+ def lookup_method(self, methodnm):
+ """ Given the method name, returns a jvmgen.Method object """
+ return self.super_class.lookup_method(methodnm)
+ def render(self, gen):
+ gen.begin_class(self, self.super_class)
+ gen.begin_constructor()
+ gen.end_constructor()
+ gen.begin_function('invoke', [],
+ self.super_class.java_argument_types,
+ self.super_class.java_return_type)
+ for i in range(len(self.super_class.java_argument_types)):
+ if not i: continue # skip the this ptr
+ gen.load_function_argument(i)
+ gen.emit(self.impl_method)
+ if self.super_class.java_return_type is not jVoid:
+ gen.return_val(self.super_class.java_return_type)
+ gen.end_function()
+ gen.end_class()
+
class Class(Node, JvmClassType):
""" Represents a class to be emitted. Note that currently, classes
@@ -321,7 +408,7 @@
gen.end_class()
-class TestDumpMethod(object):
+class BaseDumpMethod(object):
def __init__(self, db, OOCLASS, clsobj):
self.db = db
@@ -336,9 +423,21 @@
return jvmgen.Method.v(
self.clsobj, self.name, self.jargtypes[1:], self.jrettype)
- def render(self, gen):
- clsobj = self.clsobj
+ def _increase_indent(self, gen):
+ gen.load_jvm_var(jInt, 1)
+ gen.emit(jvmgen.ICONST, 2)
+ gen.emit(jvmgen.IADD)
+ gen.store_jvm_var(jInt, 1)
+
+ def _print_field_value(self, gen, fieldnm, FIELDOOTY):
+ gen.load_this_ptr()
+ fieldobj = self.clsobj.lookup_field(fieldnm)
+ fieldobj.load(gen)
+ gen.load_jvm_var(jInt, 1)
+ dumpmethod = self.db.generate_dump_method_for_ootype(FIELDOOTY)
+ gen.emit(dumpmethod)
+ def render(self, gen):
gen.begin_function(
self.name, (), self.jargtypes, self.jrettype, static=False)
@@ -350,39 +449,70 @@
gen.load_string(str)
jvmgen.PYPYDUMPINDENTED.invoke(gen)
+ self._render_guts(gen, genprint)
+
+ gen.emit(jvmgen.RETURN.for_type(jVoid))
+ gen.end_function()
+
+class InstanceDumpMethod(BaseDumpMethod):
+
+ def _render_guts(self, gen, genprint):
+ clsobj = self.clsobj
+
# Start the dump
genprint("InstanceWrapper([")
# Increment the indent
- gen.load_jvm_var(jInt, 1)
- gen.emit(jvmgen.ICONST, 2)
- gen.emit(jvmgen.IADD)
- gen.store_jvm_var(jInt, 1)
+ self._increase_indent(gen)
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
if FIELDOOTY is ootype.Void: continue
genprint("(")
- genprint(fieldnm+",")
+ genprint('"'+fieldnm+'",')
print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
# Print the value of the field:
- gen.load_this_ptr()
- fieldobj = clsobj.lookup_field(fieldnm)
- fieldobj.load(gen)
- gen.load_jvm_var(jInt, 1)
- dumpmethod = self.db.generate_dump_method_for_ootype(FIELDOOTY)
- gen.emit(dumpmethod)
+ self._print_field_value(gen, fieldnm, FIELDOOTY)
genprint(")")
# Decrement indent and dump close
genprint("])", 2)
+
+class RecordDumpMethod(BaseDumpMethod):
- gen.emit(jvmgen.RETURN.for_type(jVoid))
+ def _render_guts(self, gen, genprint):
+ clsobj = self.clsobj
- gen.end_function()
-
-
+ # Start the dump
+ genprint("StructTuple((")
+
+ # Increment the indent
+ self._increase_indent(gen)
+
+ numfields = len(self.OOCLASS._fields)
+ for i in range(numfields):
+ f_name = 'item%d' % i
+ FIELD_TYPE, f_default = self.OOCLASS._fields[f_name]
+ if FIELD_TYPE is ootype.Void:
+ continue
+
+ # Print the value of the field:
+ self._print_field_value(gen, f_name, FIELD_TYPE)
+ genprint(',')
+
+ # Decrement indent and dump close
+ genprint("))", 2)
+
+class ConstantStringDumpMethod(BaseDumpMethod):
+ """ Just prints out a string """
+
+ def __init__(self, clsobj, str):
+ BaseDumpMethod.__init__(self, None, None, clsobj)
+ self.constant_string = str
+
+ def _render_guts(self, gen, genprint):
+ genprint("'" + self.constant_string + "'")
Modified: pypy/dist/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/opcodes.py (original)
+++ pypy/dist/pypy/translator/jvm/opcodes.py Wed Jan 10 00:31:30 2007
@@ -7,7 +7,9 @@
from pypy.translator.oosupport.metavm import \
PushArg, PushAllArgs, StoreResult, InstructionList, New, DoNothing, Call,\
- SetField, GetField, CallMethod, DownCast, RuntimeNew, OOString
+ SetField, GetField, CallMethod, DownCast, RuntimeNew, OOString, CastTo
+from pypy.translator.jvm.metavm import \
+ IndirectCall
import pypy.translator.jvm.generator as jvmgen
def _check_zer(op):
@@ -29,12 +31,12 @@
'oosend': [CallMethod, StoreResult],
'ooupcast': DoNothing,
'oodowncast': [DownCast, StoreResult],
- 'oois': 'is_null',
+ 'oois': 'ref_is_eq',
'oononnull': 'is_not_null',
- #'instanceof': [CastTo, 'ldnull', 'cgt.un'],
- #'subclassof': [PushAllArgs, 'call bool [pypylib]pypy.runtime.Utils::SubclassOf(class [mscorlib]System.Type, class[mscorlib]System.Type)'],
- #'ooidentityhash': [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'],
- #'oohash': [PushAllArgs, 'callvirt instance int32 object::GetHashCode()'],
+ 'instanceof': CastTo,
+ 'subclassof': [PushAllArgs, jvmgen.SWAP, jvmgen.CLASSISASSIGNABLEFROM, StoreResult],
+ 'ooidentityhash': [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult],
+ 'oohash': [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult],
'oostring': [OOString, StoreResult],
#'ooparse_int': [PushAllArgs, 'call int32 [pypylib]pypy.runtime.Utils::OOParseInt(string, int32)'],
#'oonewcustomdict': [NewCustomDict],
@@ -42,7 +44,7 @@
'same_as': DoNothing,
#'hint': [PushArg(0), StoreResult],
'direct_call': [Call, StoreResult],
- #'indirect_call': [IndirectCall],
+ 'indirect_call': [PushAllArgs, IndirectCall, StoreResult],
#
#'cast_ptr_to_weakadr': [PushAllArgs, 'newobj instance void class %s::.ctor(object)' % WEAKREF],
#'cast_weakadr_to_ptr': [CastWeakAdrToPtr],
Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java Wed Jan 10 00:31:30 2007
@@ -201,6 +201,10 @@
dump_indented(indent, Integer.toString(i));
}
+ public static void dump_char(char c, int indent) {
+ dump_indented(indent, "'"+c+"'");
+ }
+
public static void dump_uint(int i, int indent) {
if (i >= 0)
dump_indented(indent, Integer.toString(i));
Modified: pypy/dist/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/constant.py (original)
+++ pypy/dist/pypy/translator/oosupport/constant.py Wed Jan 10 00:31:30 2007
@@ -367,8 +367,7 @@
If you overload this, overload is_inline() too.
"""
assert self.is_inline() and self.is_null()
- return gen.push_null(EXPECTED_TYPE)
-
+ return gen.push_null(EXPECTED_TYPE)
# ____________________________________________________________
# Initializing the constant
Modified: pypy/dist/pypy/translator/oosupport/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/metavm.py (original)
+++ pypy/dist/pypy/translator/oosupport/metavm.py Wed Jan 10 00:31:30 2007
@@ -405,6 +405,12 @@
generator.load(op.args[1])
generator.call_oostring(ARGTYPE)
+class _CastTo(MicroInstruction):
+ def render(self, generator, op):
+ generator.load(op.args[0])
+ INSTANCE = op.args[1].value
+ class_name = generator.db.pending_class(INSTANCE)
+ generator.isinstance(class_name)
New = _New()
@@ -418,3 +424,4 @@
CallMethod = _CallMethod()
RuntimeNew = _RuntimeNew()
OOString = _OOString()
+CastTo = _CastTo()
From exarkun at codespeak.net Wed Jan 10 02:57:34 2007
From: exarkun at codespeak.net (exarkun at codespeak.net)
Date: Wed, 10 Jan 2007 02:57:34 +0100 (CET)
Subject: [pypy-svn] r36398 - in pypy/dist/pypy/lib: . test2
Message-ID: <20070110015734.73F4F10075@code0.codespeak.net>
Author: exarkun
Date: Wed Jan 10 02:57:32 2007
New Revision: 36398
Added:
pypy/dist/pypy/lib/test2/test_cstringio.py
Modified:
pypy/dist/pypy/lib/cStringIO.py
Log:
Add cStringIO.StringIO.reset - an alternate spelling of seek(0, 0) only available on cStringIO objects
Modified: pypy/dist/pypy/lib/cStringIO.py
==============================================================================
--- pypy/dist/pypy/lib/cStringIO.py (original)
+++ pypy/dist/pypy/lib/cStringIO.py Wed Jan 10 02:57:32 2007
@@ -1,6 +1,13 @@
#
-# One-liner implementation of cStringIO
+# StringIO-based cStringIO implementation.
#
from StringIO import *
from StringIO import __doc__
+
+class StringIO(StringIO):
+ def reset(self):
+ """
+ reset() -- Reset the file position to the beginning
+ """
+ self.seek(0, 0)
Added: pypy/dist/pypy/lib/test2/test_cstringio.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/lib/test2/test_cstringio.py Wed Jan 10 02:57:32 2007
@@ -0,0 +1,30 @@
+
+"""
+Tests for the PyPy cStringIO implementation.
+"""
+
+from pypy.conftest import gettestobjspace
+
+class AppTestcStringIO:
+ def setup_class(cls):
+ cls.space = gettestobjspace()
+ cls.w_io = cls.space.appexec([], "(): import cStringIO; return cStringIO")
+ cls.w_bytes = cls.space.wrap('some bytes')
+
+
+ def test_reset(self):
+ """
+ Test that the reset method of cStringIO objects sets the position
+ marker to the beginning of the stream.
+ """
+ io = self.io.StringIO()
+ io.write(self.bytes)
+ assert io.read() == ''
+ io.reset()
+ assert io.read() == self.bytes
+
+ io = self.io.StringIO(self.bytes)
+ assert io.read() == self.bytes
+ assert io.read() == ''
+ io.reset()
+ assert io.read() == self.bytes
From exarkun at codespeak.net Wed Jan 10 03:01:28 2007
From: exarkun at codespeak.net (exarkun at codespeak.net)
Date: Wed, 10 Jan 2007 03:01:28 +0100 (CET)
Subject: [pypy-svn] r36399 - in pypy/dist/pypy: module/signal
module/signal/test translator/goal
Message-ID: <20070110020128.312C810071@code0.codespeak.net>
Author: exarkun
Date: Wed Jan 10 03:01:26 2007
New Revision: 36399
Added:
pypy/dist/pypy/module/signal/app_signal.py
Modified:
pypy/dist/pypy/module/signal/__init__.py
pypy/dist/pypy/module/signal/interp_signal.py
pypy/dist/pypy/module/signal/test/test_signal.py
pypy/dist/pypy/translator/goal/app_main.py
Log:
Fix signal.signal return value, add signal.getsignal and signal.default_int_handler
Modified: pypy/dist/pypy/module/signal/__init__.py
==============================================================================
--- pypy/dist/pypy/module/signal/__init__.py (original)
+++ pypy/dist/pypy/module/signal/__init__.py Wed Jan 10 03:01:26 2007
@@ -3,13 +3,15 @@
class Module(MixedModule):
interpleveldefs = {
- 'signal': 'interp_signal.signal',
- 'NSIG': 'space.wrap(interp_signal.NSIG)',
- 'SIG_DFL': 'space.wrap(interp_signal.SIG_DFL)',
- 'SIG_IGN': 'space.wrap(interp_signal.SIG_IGN)',
+ 'signal': 'interp_signal.signal',
+ 'getsignal': 'interp_signal.getsignal',
+ 'NSIG': 'space.wrap(interp_signal.NSIG)',
+ 'SIG_DFL': 'space.wrap(interp_signal.SIG_DFL)',
+ 'SIG_IGN': 'space.wrap(interp_signal.SIG_IGN)',
}
appleveldefs = {
+ 'default_int_handler': 'app_signal.default_int_handler',
}
def buildloaders(cls):
Added: pypy/dist/pypy/module/signal/app_signal.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/module/signal/app_signal.py Wed Jan 10 03:01:26 2007
@@ -0,0 +1,10 @@
+
+
+def default_int_handler(signum, frame):
+ """
+ default_int_handler(...)
+
+ The default handler for SIGINT installed by Python.
+ It raises KeyboardInterrupt.
+ """
+ raise KeyboardInterrupt()
Modified: pypy/dist/pypy/module/signal/interp_signal.py
==============================================================================
--- pypy/dist/pypy/module/signal/interp_signal.py (original)
+++ pypy/dist/pypy/module/signal/interp_signal.py Wed Jan 10 03:01:26 2007
@@ -66,30 +66,60 @@
w_frame = space.w_None
space.call_function(w_handler, space.wrap(self.signum), w_frame)
+
+def getsignal(space, signum):
+ """
+ getsignal(sig) -> action
+
+ Return the current action for the given signal. The return value can be:
+ SIG_IGN -- if the signal is being ignored
+ SIG_DFL -- if the default action for the signal is in effect
+ None -- if an unknown handler is in effect (XXX UNIMPLEMENTED)
+ anything else -- the callable Python object used as a handler
+ """
+ action = CheckSignalAction.get(space)
+ if signum in action.handlers_w:
+ return action.handlers_w[signum]
+ return space.wrap(SIG_DFL)
+getsignal.unwrap_spec = [ObjSpace, int]
+
+
def signal(space, signum, w_handler):
+ """
+ signal(sig, action) -> action
+
+ Set the action for the given signal. The action can be SIG_DFL,
+ SIG_IGN, or a callable Python object. The previous action is
+ returned. See getsignal() for possible return values.
+
+ *** IMPORTANT NOTICE ***
+ A signal handler function is called with two arguments:
+ the first is the signal number, the second is the interrupted stack frame.
+ """
ec = space.getexecutioncontext()
main_ec = space.threadlocals.getmainthreadvalue()
+
+ old_handler = getsignal(space, signum)
+
if ec is not main_ec:
raise OperationError(space.w_ValueError,
space.wrap("signal() must be called from the "
"main thread"))
action = CheckSignalAction.get(space)
if space.eq_w(w_handler, space.wrap(SIG_DFL)):
- if signum in action.handlers_w:
- del action.handlers_w[signum]
pypysig_default(signum)
+ action.handlers_w[signum] = w_handler
elif space.eq_w(w_handler, space.wrap(SIG_IGN)):
- if signum in action.handlers_w:
- del action.handlers_w[signum]
pypysig_ignore(signum)
+ action.handlers_w[signum] = w_handler
else:
if not space.is_true(space.callable(w_handler)):
raise OperationError(space.w_TypeError,
space.wrap("'handler' must be a callable "
"or SIG_DFL or SIG_IGN"))
- action.handlers_w[signum] = w_handler
pypysig_setflag(signum)
- # XXX return value missing
+ action.handlers_w[signum] = w_handler
+ return old_handler
signal.unwrap_spec = [ObjSpace, int, W_Root]
# ____________________________________________________________
Modified: pypy/dist/pypy/module/signal/test/test_signal.py
==============================================================================
--- pypy/dist/pypy/module/signal/test/test_signal.py (original)
+++ pypy/dist/pypy/module/signal/test/test_signal.py Wed Jan 10 03:01:26 2007
@@ -49,3 +49,69 @@
assert received == []
signal.signal(signal.SIGUSR1, signal.SIG_DFL)
+
+
+ def test_default_return(self):
+ """
+ Test that signal.signal returns SIG_DFL if that is the current handler.
+ """
+ from signal import signal, SIGUSR1, SIG_DFL, SIG_IGN
+
+ try:
+ for handler in SIG_DFL, SIG_IGN, lambda *a: None:
+ signal(SIGUSR1, SIG_DFL)
+ assert signal(SIGUSR1, handler) == SIG_DFL
+ finally:
+ signal(SIGUSR1, SIG_DFL)
+
+
+ def test_ignore_return(self):
+ """
+ Test that signal.signal returns SIG_IGN if that is the current handler.
+ """
+ from signal import signal, SIGUSR1, SIG_DFL, SIG_IGN
+
+ try:
+ for handler in SIG_DFL, SIG_IGN, lambda *a: None:
+ signal(SIGUSR1, SIG_IGN)
+ assert signal(SIGUSR1, handler) == SIG_IGN
+ finally:
+ signal(SIGUSR1, SIG_DFL)
+
+
+ def test_obj_return(self):
+ """
+ Test that signal.signal returns a Python object if one is the current
+ handler.
+ """
+ from signal import signal, SIGUSR1, SIG_DFL, SIG_IGN
+ def installed(*a):
+ pass
+
+ try:
+ for handler in SIG_DFL, SIG_IGN, lambda *a: None:
+ signal(SIGUSR1, installed)
+ assert signal(SIGUSR1, handler) is installed
+ finally:
+ signal(SIGUSR1, SIG_DFL)
+
+
+ def test_getsignal(self):
+ """
+ Test that signal.getsignal returns the currently installed handler.
+ """
+ from signal import getsignal, signal, SIGUSR1, SIG_DFL, SIG_IGN
+
+ def handler(*a):
+ pass
+
+ try:
+ assert getsignal(SIGUSR1) == SIG_DFL
+ signal(SIGUSR1, SIG_DFL)
+ assert getsignal(SIGUSR1) == SIG_DFL
+ signal(SIGUSR1, SIG_IGN)
+ assert getsignal(SIGUSR1) == SIG_IGN
+ signal(SIGUSR1, handler)
+ assert getsignal(SIGUSR1) is handler
+ finally:
+ signal(SIGUSR1, SIG_DFL)
Modified: pypy/dist/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/dist/pypy/translator/goal/app_main.py (original)
+++ pypy/dist/pypy/translator/goal/app_main.py Wed Jan 10 03:01:26 2007
@@ -221,9 +221,7 @@
except ImportError:
pass
else:
- def keyboard_interrupt_handler(*args):
- raise KeyboardInterrupt
- signal.signal(signal.SIGINT, keyboard_interrupt_handler)
+ signal.signal(signal.SIGINT, signal.default_int_handler)
signal.signal(signal.SIGPIPE, signal.SIG_IGN)
try:
From exarkun at codespeak.net Wed Jan 10 03:05:29 2007
From: exarkun at codespeak.net (exarkun at codespeak.net)
Date: Wed, 10 Jan 2007 03:05:29 +0100 (CET)
Subject: [pypy-svn] r36400 - in pypy/dist/pypy: module/posix
module/posix/test rpython rpython/module rpython/module/test
translator/c translator/c/src translator/c/test
Message-ID: <20070110020529.620A410071@code0.codespeak.net>
Author: exarkun
Date: Wed Jan 10 03:05:26 2007
New Revision: 36400
Modified:
pypy/dist/pypy/module/posix/__init__.py
pypy/dist/pypy/module/posix/interp_posix.py
pypy/dist/pypy/module/posix/test/test_posix2.py
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/rpython/module/test/test_ll_os.py
pypy/dist/pypy/translator/c/extfunc.py
pypy/dist/pypy/translator/c/src/ll_os.h
pypy/dist/pypy/translator/c/test/test_extfunc.py
Log:
Add os.access wrapper and low-level implementation for the C backend
Modified: pypy/dist/pypy/module/posix/__init__.py
==============================================================================
--- pypy/dist/pypy/module/posix/__init__.py (original)
+++ pypy/dist/pypy/module/posix/__init__.py Wed Jan 10 03:05:26 2007
@@ -33,6 +33,7 @@
'lstat' : 'interp_posix.lstat',
'dup' : 'interp_posix.dup',
'dup2' : 'interp_posix.dup2',
+ 'access' : 'interp_posix.access',
'system' : 'interp_posix.system',
'unlink' : 'interp_posix.unlink',
'remove' : 'interp_posix.remove',
Modified: pypy/dist/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/dist/pypy/module/posix/interp_posix.py (original)
+++ pypy/dist/pypy/module/posix/interp_posix.py Wed Jan 10 03:05:26 2007
@@ -162,6 +162,19 @@
raise wrap_oserror(space, e)
dup2.unwrap_spec = [ObjSpace, int, int]
+def access(space, path, mode):
+ """
+ access(path, mode) -> 1 if granted, 0 otherwise
+
+ Use the real uid/gid to test for access to a path. Note that most
+ operations will use the effective uid/gid, therefore this routine can
+ be used in a suid/sgid environment to test if the invoking user has the
+ specified access to the path. The mode argument can be F_OK to test
+ existence, or the inclusive-OR of R_OK, W_OK, and X_OK.
+ """
+ return space.wrap(os.access(path, mode))
+access.unwrap_spec = [ObjSpace, str, int]
+
def system(space, cmd):
"""Execute the command (a string) in a subshell."""
try:
Modified: pypy/dist/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/dist/pypy/module/posix/test/test_posix2.py (original)
+++ pypy/dist/pypy/module/posix/test/test_posix2.py Wed Jan 10 03:05:26 2007
@@ -9,6 +9,7 @@
mod.path.write("this is a test")
pdir = udir.ensure('posixtestdir', dir=True)
pdir.join('file1').write("test1")
+ os.chmod(str(pdir.join('file1')), 0600)
pdir.join('file2').write("test2")
pdir.join('another_longer_file_name').write("test3")
mod.pdir = pdir
@@ -87,6 +88,16 @@
'file1',
'file2']
+
+ def test_access(self):
+ pdir = self.pdir + '/file1'
+ posix = self.posix
+
+ assert posix.access(pdir, posix.R_OK)
+ assert posix.access(pdir, posix.W_OK)
+ assert not posix.access(pdir, posix.X_OK)
+
+
def test_strerror(self):
assert isinstance(self.posix.strerror(0), str)
assert isinstance(self.posix.strerror(1), str)
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Wed Jan 10 03:05:26 2007
@@ -197,6 +197,7 @@
declare(os.close , noneannotation, 'll_os/close')
declare(os.dup , int , 'll_os/dup')
declare(os.dup2 , noneannotation, 'll_os/dup2')
+declare(os.access , int , 'll_os/access')
declare(os.lseek , r_longlong , 'll_os/lseek')
declare(os.isatty , bool , 'll_os/isatty')
if hasattr(posix, 'ftruncate'):
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Wed Jan 10 03:05:26 2007
@@ -56,6 +56,10 @@
os.dup2(old_fd, new_fd)
ll_os_dup2.suggested_primitive = True
+ def ll_os_access(cls, path, mode):
+ return os.access(cls.from_rstr(path), mode)
+ ll_os_access.suggested_primitive = True
+
def ll_os_lseek(cls, fd,pos,how):
return r_longlong(os.lseek(fd,pos,how))
ll_os_lseek.suggested_primitive = True
Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Wed Jan 10 03:05:26 2007
@@ -3,6 +3,17 @@
from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl
+def test_access():
+ filename = str(udir.join('test_access.txt'))
+ rsfilename = impl.to_rstr(filename)
+
+ fd = file(filename, 'w')
+ fd.close()
+
+ for mode in os.R_OK, os.W_OK, os.X_OK, os.R_OK | os.W_OK | os.X_OK:
+ assert os.access(filename, mode) == impl.ll_os_access(rsfilename, mode)
+
+
def test_open_read_write_close():
filename = str(udir.join('test_open_read_write_close.txt'))
rsfilename = impl.to_rstr(filename)
Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/dist/pypy/translator/c/extfunc.py Wed Jan 10 03:05:26 2007
@@ -31,6 +31,7 @@
impl.ll_os_close.im_func: 'LL_os_close',
impl.ll_os_dup.im_func: 'LL_os_dup',
impl.ll_os_dup2.im_func: 'LL_os_dup2',
+ impl.ll_os_access.im_func: 'LL_os_access',
impl.ll_os_stat.im_func: 'LL_os_stat',
impl.ll_os_fstat.im_func: 'LL_os_fstat',
impl.ll_os_lstat.im_func: 'LL_os_lstat',
Modified: pypy/dist/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h (original)
+++ pypy/dist/pypy/translator/c/src/ll_os.h Wed Jan 10 03:05:26 2007
@@ -57,6 +57,7 @@
void LL_os_close(int fd);
int LL_os_dup(int fd);
void LL_os_dup2(int old_fd, int new_fd);
+int LL_os_access(RPyString *filename, int mode);
RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st);
RPySTAT_RESULT* LL_os_stat(RPyString * fname);
RPySTAT_RESULT* LL_os_lstat(RPyString * fname);
@@ -153,6 +154,11 @@
RPYTHON_RAISE_OSERROR(errno);
}
+int LL_os_access(RPyString *filename, int mode) {
+ int n = access(RPyString_AsString(filename), mode);
+ return (n == 0);
+}
+
#ifdef LL_NEED_OS_STAT
RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st) {
Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_extfunc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_extfunc.py Wed Jan 10 03:05:26 2007
@@ -120,6 +120,16 @@
f1()
os.unlink(filename)
+
+def test_os_access():
+ filename = str(py.magic.autopath())
+ def call_access(path, mode):
+ return os.access(path, mode)
+ f = compile(call_access, [str, int])
+ for mode in os.R_OK, os.W_OK, os.X_OK, (os.R_OK | os.W_OK | os.X_OK):
+ assert f(filename, mode) == os.access(filename, mode)
+
+
def test_os_stat():
filename = str(py.magic.autopath())
def call_stat():
From pedronis at codespeak.net Wed Jan 10 10:49:56 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Wed, 10 Jan 2007 10:49:56 +0100 (CET)
Subject: [pypy-svn] r36402 - pypy/dist/pypy/jit/timeshifter
Message-ID: <20070110094956.6890C1006E@code0.codespeak.net>
Author: pedronis
Date: Wed Jan 10 10:49:46 2007
New Revision: 36402
Modified:
pypy/dist/pypy/jit/timeshifter/rcontainer.py
Log:
fix blocked block failures.
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Wed Jan 10 10:49:46 2007
@@ -82,11 +82,12 @@
self.immutable = TYPE._hints.get('immutable', False)
self.noidentity = TYPE._hints.get('noidentity', False)
+ self.null = self.PTRTYPE._defl()
+ self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
+
if TYPE._hints.get('virtualizable', False):
self.__class__ = VirtualizableStructTypeDesc
self.VStructCls = VirtualizableStruct
- outside_null = self.PTRTYPE._defl()
- self.gv_defl_outside = RGenOp.constPrebuiltGlobal(outside_null)
else:
self.VStructCls = VirtualStruct
@@ -132,7 +133,7 @@
vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
for desc in self.fielddescs]
outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind,
- self.gv_defl_outside)
+ self.gv_null)
vstruct.content_boxes.append(outsidebox)
box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
box.content = vstruct
@@ -344,7 +345,7 @@
typedesc = self.typedesc
assert typedesc is not None
gv_outside = self.content_boxes[-1].genvar
- if gv_outside is typedesc.gv_defl_outside:
+ if gv_outside is typedesc.gv_null:
gv_outside = builder.genop_malloc_fixedsize(typedesc.alloctoken)
self.content_boxes[-1].genvar = gv_outside
# xxx jitstate please
From mwh at codespeak.net Wed Jan 10 12:09:04 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Wed, 10 Jan 2007 12:09:04 +0100 (CET)
Subject: [pypy-svn] r36403 - in pypy/dist/pypy/jit/codegen/ppc: . test
Message-ID: <20070110110904.DBA2810075@code0.codespeak.net>
Author: mwh
Date: Wed Jan 10 12:09:00 2007
New Revision: 36403
Added:
pypy/dist/pypy/jit/codegen/ppc/test/test_interp.py
Modified:
pypy/dist/pypy/jit/codegen/ppc/codebuf.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
steps on the way to being able to "run" the jit ppc code generation on the
llinterp.
Modified: pypy/dist/pypy/jit/codegen/ppc/codebuf.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/codebuf.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/codebuf.py Wed Jan 10 12:09:00 2007
@@ -50,8 +50,8 @@
class MachineCodeBlock:
def __init__(self, _data, _size, _pos):
- self._data = _data
self._size = _size
+ self._data = _data
self._pos = _pos
def write(self, data):
@@ -79,19 +79,47 @@
class ExistingCodeBlock(MachineCodeBlock):
def __init__(self, start, end):
- self._size = (end-start)/4
- p = c_void_p(start)
- self._data = cast(p, POINTER(c_int * self._size))
- self._pos = 0
+ _size = (end-start)/4
+ _data = cast(c_void_p(start), POINTER(c_int * _size))
+ MachineCodeBlock.__init__(self, _data, _size, 0)
class OwningMachineCodeBlock(MachineCodeBlock):
+ def __init__(self, size_in_bytes):
+ assert size_in_bytes % 4 == 0
+ res = alloc(size_in_bytes)
+ _size = size_in_bytes/4
+ _data = cast(res, POINTER(c_int * _size))
+ MachineCodeBlock.__init__(self, _data, _size, 0)
+
def __del__(self):
free(cast(self._data, PTR), self._size * 4)
-def new_block(size_in_bytes):
- assert size_in_bytes % 4 == 0
- res = alloc(size_in_bytes)
- return OwningMachineCodeBlock(
- cast(res, POINTER(c_int * (size_in_bytes / 4))),
- size_in_bytes/4,
- 0)
+# ------------------------------------------------------------
+
+class LLTypeMachineCodeBlock(MachineCodeBlock):
+ class State:
+ pass
+ state = State()
+ state.base = 1
+
+ def __init__(self, map_size):
+ self._size = map_size/4
+ self._pos = 0
+ self._base = LLTypeMachineCodeBlock.state.base
+ LLTypeMachineCodeBlock.state.base += 2 * map_size
+
+ def write(self, data):
+ if self._pos + 1 > self._size:
+ raise CodeBlockOverflow
+ self._pos += 1
+
+ def tell(self):
+ return self._base + 4 * self._pos
+
+ def reserve(self, _size):
+ return LLTypeMachineCodeBlock(_size)
+
+class LLTypeExistingCodeBlock(LLTypeMachineCodeBlock):
+ def __init__(self, start, end):
+ _size = (end-start)
+ LLTypeMachineCodeBlock.__init__(self, _size)
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Wed Jan 10 12:09:00 2007
@@ -424,7 +424,7 @@
if self.final_jump_addr != 0:
mc = self.rgenop.open_mc()
target = mc.tell()
- self.asm.mc = codebuf.ExistingCodeBlock(self.final_jump_addr, self.final_jump_addr+8)
+ self.asm.mc = self.rgenop.ExistingCodeBlock(self.final_jump_addr, self.final_jump_addr+8)
self.asm.load_word(rSCRATCH, target)
self.asm.mc = mc
self.emit_stack_adjustment()
@@ -438,7 +438,7 @@
def maybe_patch_start_here(self):
if self.patch_start_here:
mc = self.asm.mc
- self.asm.mc = codebuf.ExistingCodeBlock(self.patch_start_here, self.patch_start_here+8)
+ self.asm.mc = self.rgenop.ExistingCodeBlock(self.patch_start_here, self.patch_start_here+8)
self.asm.load_word(rSCRATCH, mc.tell())
self.asm.mc = mc
self.patch_start_here = 0
@@ -573,16 +573,10 @@
return
#print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
# we build an addi instruction by hand here
- opcode = 14 << 26
- rD = rSCRATCH << 21
- rA = rFP << 16
- # if we decided to use r0 as the frame pointer, this would
- # emit addi rFOO, r0, SIMM which would just load SIMM into
- # rFOO and be "unlikely" to work
- assert rA != 0
- SIMM = (-newsize) & 0xFFFF
- p_instruction = cast(c_void_p(self.stack_adj_addr), POINTER(c_int*1))
- p_instruction.contents[0] = opcode | rD | rA | SIMM
+ mc = self.asm.mc
+ self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
+ self.asm.addi(rSCRATCH, rFP, -newsize)
+ self.asm.mc = mc
def op_int_mul(self, gv_x, gv_y):
gv_result = Var()
@@ -799,11 +793,14 @@
# ----------------------------------------------------------------
# ppc-specific interface:
+ MachineCodeBlock = codebuf.OwningMachineCodeBlock
+ ExistingCodeBlock = codebuf.ExistingCodeBlock
+
def open_mc(self):
if self.mcs:
return self.mcs.pop()
else:
- return codebuf.new_block(65536) # XXX supposed infinite for now
+ return self.MachineCodeBlock(65536) # XXX supposed infinite for now
def close_mc(self, mc):
## from pypy.translator.asm.ppcgen.asmfunc import get_ppcgen
Added: pypy/dist/pypy/jit/codegen/ppc/test/test_interp.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_interp.py Wed Jan 10 12:09:00 2007
@@ -0,0 +1,21 @@
+from pypy.jit.codegen.ppc import codebuf, rgenop
+from pypy.rpython.lltypesystem import lltype
+from pypy.jit.codegen.test import rgenop_tests
+from pypy.rpython.test.test_llinterp import interpret
+from pypy.jit.codegen.ppc.test import test_rgenop
+
+class LLTypeRGenOp(rgenop.RPPCGenOp):
+ MachineCodeBlock = codebuf.LLTypeMachineCodeBlock
+ ExistingCodeBlock = codebuf.LLTypeExistingCodeBlock
+
+def test_simple():
+ FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
+ def f(n):
+ rgenop = LLTypeRGenOp()
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_add_one, [gv_x] = rgenop.newgraph(sigtoken, "adder")
+ gv_result = builder.genop2("int_add", gv_x, rgenop.genconst(n))
+ builder.finish_and_return(sigtoken, gv_result)
+ builder.end()
+ res = interpret(f, [5], policy=rgenop_tests.GENOP_POLICY)
+ # just testing that this didn't crash
From mwh at codespeak.net Wed Jan 10 14:01:10 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Wed, 10 Jan 2007 14:01:10 +0100 (CET)
Subject: [pypy-svn] r36404 - in pypy/dist/pypy/jit/codegen: i386/test ppc
ppc/test
Message-ID: <20070110130110.02C8C10080@code0.codespeak.net>
Author: mwh
Date: Wed Jan 10 14:01:09 2007
New Revision: 36404
Added:
pypy/dist/pypy/jit/codegen/ppc/test/test_interp_ts.py
Modified:
pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
pypy/dist/pypy/jit/codegen/ppc/conftest.py
Log:
add test_interp_ts for ppc, skipped unless you pass --run-interp-tests to
py.test
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_interp_ts.py Wed Jan 10 14:01:09 2007
@@ -1,10 +1,11 @@
import os, py
-py.test.skip("these tests take ages and are not really useful")
from pypy.annotation import model as annmodel
from pypy.jit.timeshifter.test import test_timeshift
from pypy.jit.codegen.i386.rgenop import RI386GenOp, IntConst
from pypy.jit.codegen.i386.test.test_operation import RGenOpPacked
+def setup_module(mod):
+ py.test.skip("these tests take ages and are not really useful")
class Whatever(object):
def __eq__(self, other):
Modified: pypy/dist/pypy/jit/codegen/ppc/conftest.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/conftest.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/conftest.py Wed Jan 10 14:01:09 2007
@@ -21,6 +21,9 @@
Option('--trap', action="store_true", default=False,
dest="trap",
help=""),
+ Option('--run-interp-tests', action="store_true", default=False,
+ dest="run_interp_tests",
+ help=""),
Option('--debug-print', action="store_true", default=False,
dest="debug_print",
help=""))
Added: pypy/dist/pypy/jit/codegen/ppc/test/test_interp_ts.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_interp_ts.py Wed Jan 10 14:01:09 2007
@@ -0,0 +1,21 @@
+from pypy.jit.codegen.ppc.conftest import option
+import py
+from pypy.jit.codegen.i386.test.test_interp_ts import I386LLInterpTimeshiftingTestMixin
+from pypy.jit.timeshifter.test import test_timeshift
+
+def setup_module(mod):
+ if not option.run_interp_tests:
+ py.test.skip("these tests take ages and are not really useful")
+
+
+class PPCLLInterpTimeshiftingTestMixin(I386LLInterpTimeshiftingTestMixin):
+ from pypy.jit.codegen.ppc.test.test_interp import LLTypeRGenOp as RGenOp
+
+class TestTimeshiftPPC(PPCLLInterpTimeshiftingTestMixin,
+ test_timeshift.TestTimeshift):
+
+ # for the individual tests see
+ # ====> ../../../timeshifter/test/test_timeshift.py
+
+ pass
+
From cfbolz at codespeak.net Wed Jan 10 15:23:57 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 15:23:57 +0100 (CET)
Subject: [pypy-svn] r36405 - in pypy/dist/pypy: config objspace/std
objspace/std/test
Message-ID: <20070110142357.70D6810078@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 15:23:53 2007
New Revision: 36405
Added:
pypy/dist/pypy/objspace/std/test/test_versionedtype.py
Modified:
pypy/dist/pypy/config/pypyoption.py
pypy/dist/pypy/objspace/std/typeobject.py
pypy/dist/pypy/objspace/std/typetype.py
Log:
(pedronis, cfbolz): adding a version tag to types to check whether they
changed. used only when a new config option withversiontypes.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Wed Jan 10 15:23:53 2007
@@ -140,6 +140,11 @@
"list is mutaged",
default=False),
+ BoolOption("withtypeversion",
+ "version type objects when changing them",
+ cmdline=None,
+ default=False),
+
BoolOption("optimized_int_add",
"special case the addition of two integers in BINARY_ADD",
default=False),
Added: pypy/dist/pypy/objspace/std/test/test_versionedtype.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/test/test_versionedtype.py Wed Jan 10 15:23:53 2007
@@ -0,0 +1,56 @@
+from pypy.objspace.std.test import test_typeobject
+from pypy.conftest import gettestobjspace
+
+class TestVersionedType(test_typeobject.TestTypeObject):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True})
+
+ def test_tag_changes(self):
+ space = self.space
+ w_types = space.appexec([], """():
+ class A(object):
+ def f(self): pass
+ class B(A):
+ pass
+ class metatype(type):
+ pass
+ class C(object):
+ __metaclass__ = metatype
+ return A, B, C
+ """)
+ w_A, w_B, w_C = space.unpackiterable(w_types)
+ atag = w_A.version_tag
+ btag = w_B.version_tag
+ assert atag is not None
+ assert btag is not None
+ assert w_C.version_tag is None
+ assert atag is not btag
+ w_types = space.appexec([w_A, w_B], """(A, B):
+ B.g = lambda self: None
+ """)
+ assert w_B.version_tag is not btag
+ assert w_A.version_tag is atag
+ btag = w_B.version_tag
+ w_types = space.appexec([w_A, w_B], """(A, B):
+ A.f = lambda self: None
+ """)
+ assert w_B.version_tag is not btag
+ assert w_A.version_tag is not atag
+ atag = w_A.version_tag
+ btag = w_B.version_tag
+ assert atag is not btag
+ w_types = space.appexec([w_A, w_B], """(A, B):
+ del A.f
+ """)
+ assert w_B.version_tag is not btag
+ assert w_A.version_tag is not atag
+ atag = w_A.version_tag
+ btag = w_B.version_tag
+ assert atag is not btag
+
+
+class AppTestVersionedType(test_typeobject.AppTestTypeObject):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True})
+
+
Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py (original)
+++ pypy/dist/pypy/objspace/std/typeobject.py Wed Jan 10 15:23:53 2007
@@ -38,6 +38,9 @@
return "_%s%s" % (klass, name)
+class VersionTag(object):
+ pass
+
class W_TypeObject(W_Object):
from pypy.objspace.std.typetype import type_typedef as typedef
@@ -200,6 +203,8 @@
w_self.weakrefable = True
w_type = space.type(w_self)
if not space.is_w(w_type, space.w_type):
+ if space.config.objspace.std.withtypeversion:
+ w_self.version_tag = None
w_self.mro_w = []
mro_func = w_type.lookup('mro')
mro_func_args = Arguments(space, [w_self])
@@ -207,6 +212,17 @@
w_self.mro_w = space.unpackiterable(w_mro)
return
w_self.mro_w = w_self.compute_mro()
+ if space.config.objspace.std.withtypeversion:
+ w_self.version_tag = VersionTag()
+
+ def mutated(w_self):
+ space = w_self.space
+ assert space.config.objspace.std.withtypeversion
+ if w_self.version_tag is not None:
+ w_self.version_tag = VersionTag()
+ subclasses_w = w_self.get_subclasses()
+ for w_subclass in subclasses_w:
+ w_subclass.mutated()
def ready(w_self):
for w_base in w_self.bases_w:
@@ -352,6 +368,16 @@
del w_self.weak_subclasses_w[i]
return
+ def get_subclasses(w_self):
+ space = w_self.space
+ subclasses_w = []
+ for w_ref in w_self.weak_subclasses_w:
+ w_ob = space.call_function(w_ref)
+ if not space.is_w(w_ob, space.w_None):
+ subclasses_w.append(w_ob)
+ return subclasses_w
+
+
# for now, weakref support for W_TypeObject is hard to get automatically
_lifeline_ = None
def getweakref(self):
@@ -418,6 +444,8 @@
# Note. This is exactly the same thing as descroperation.descr__setattr__,
# but it is needed at bootstrap to avoid a call to w_type.getdict() which
# would un-lazify the whole type.
+ if space.config.objspace.std.withtypeversion:
+ w_type.mutated()
name = space.str_w(w_name)
w_descr = space.lookup(w_type, name)
if w_descr is not None:
@@ -427,6 +455,8 @@
w_type.dict_w[name] = w_value
def delattr__Type_ANY(space, w_type, w_name):
+ if space.config.objspace.std.withtypeversion:
+ w_type.mutated()
if w_type.lazyloaders:
w_type._freeze_() # force un-lazification
name = space.str_w(w_name)
@@ -441,6 +471,7 @@
except KeyError:
raise OperationError(space.w_AttributeError, w_name)
+
# ____________________________________________________________
Modified: pypy/dist/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typetype.py (original)
+++ pypy/dist/pypy/objspace/std/typetype.py Wed Jan 10 15:23:53 2007
@@ -248,12 +248,7 @@
def descr___subclasses__(space, w_type):
"""Return the list of immediate subclasses."""
w_type = _check(space, w_type)
- subclasses_w = []
- for w_ref in w_type.weak_subclasses_w:
- w_ob = space.call_function(w_ref)
- if not space.is_w(w_ob, space.w_None):
- subclasses_w.append(w_ob)
- return space.newlist(subclasses_w)
+ return space.newlist(w_type.get_subclasses())
# ____________________________________________________________
From cfbolz at codespeak.net Wed Jan 10 15:39:12 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 15:39:12 +0100 (CET)
Subject: [pypy-svn] r36406 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20070110143912.ACDE710070@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 15:39:11 2007
New Revision: 36406
Modified:
pypy/dist/pypy/objspace/std/test/test_versionedtype.py
pypy/dist/pypy/objspace/std/typeobject.py
Log:
(pedronis, cfbolz): a test that surprisingly passes, add a comment why.
Modified: pypy/dist/pypy/objspace/std/test/test_versionedtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_versionedtype.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_versionedtype.py Wed Jan 10 15:39:11 2007
@@ -5,7 +5,7 @@
def setup_class(cls):
cls.space = gettestobjspace(**{"objspace.std.withtypeversion": True})
- def test_tag_changes(self):
+ def get_three_classes(self):
space = self.space
w_types = space.appexec([], """():
class A(object):
@@ -18,7 +18,11 @@
__metaclass__ = metatype
return A, B, C
""")
- w_A, w_B, w_C = space.unpackiterable(w_types)
+ return space.unpackiterable(w_types)
+
+ def test_tag_changes(self):
+ space = self.space
+ w_A, w_B, w_C = self.get_three_classes()
atag = w_A.version_tag
btag = w_B.version_tag
assert atag is not None
@@ -48,6 +52,18 @@
btag = w_B.version_tag
assert atag is not btag
+ def test_tag_changes_when_bases_change(self):
+ space = self.space
+ w_A, w_B, w_C = self.get_three_classes()
+ atag = w_A.version_tag
+ btag = w_B.version_tag
+ w_types = space.appexec([w_A, w_B, w_C], """(A, B, C):
+ class D(object):
+ pass
+ B.__bases__ = (D, )
+ """)
+ assert w_B.version_tag is not btag
+
class AppTestVersionedType(test_typeobject.AppTestTypeObject):
def setup_class(cls):
Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py (original)
+++ pypy/dist/pypy/objspace/std/typeobject.py Wed Jan 10 15:39:11 2007
@@ -445,6 +445,7 @@
# but it is needed at bootstrap to avoid a call to w_type.getdict() which
# would un-lazify the whole type.
if space.config.objspace.std.withtypeversion:
+ # also takes care of assignments to __bases__
w_type.mutated()
name = space.str_w(w_name)
w_descr = space.lookup(w_type, name)
From cfbolz at codespeak.net Wed Jan 10 15:47:39 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 15:47:39 +0100 (CET)
Subject: [pypy-svn] r36407 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20070110144739.0A47410070@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 15:47:38 2007
New Revision: 36407
Modified:
pypy/dist/pypy/objspace/std/test/test_versionedtype.py
pypy/dist/pypy/objspace/std/typeobject.py
pypy/dist/pypy/objspace/std/typetype.py
Log:
(pedronis, cfbolz): on second thought, if somebody changes bases he deserves
not getting caching.
Modified: pypy/dist/pypy/objspace/std/test/test_versionedtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_versionedtype.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_versionedtype.py Wed Jan 10 15:47:38 2007
@@ -62,7 +62,7 @@
pass
B.__bases__ = (D, )
""")
- assert w_B.version_tag is not btag
+ assert w_B.version_tag is None
class AppTestVersionedType(test_typeobject.AppTestTypeObject):
Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py (original)
+++ pypy/dist/pypy/objspace/std/typeobject.py Wed Jan 10 15:47:38 2007
@@ -445,7 +445,6 @@
# but it is needed at bootstrap to avoid a call to w_type.getdict() which
# would un-lazify the whole type.
if space.config.objspace.std.withtypeversion:
- # also takes care of assignments to __bases__
w_type.mutated()
name = space.str_w(w_name)
w_descr = space.lookup(w_type, name)
Modified: pypy/dist/pypy/objspace/std/typetype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typetype.py (original)
+++ pypy/dist/pypy/objspace/std/typetype.py Wed Jan 10 15:47:38 2007
@@ -170,6 +170,9 @@
raise OperationError(space.w_TypeError,
space.wrap("__bases__ assignment: '%s' object layout differs from '%s'" %
(w_type.getname(space, '?'), new_base.getname(space, '?'))))
+ if space.config.objspace.std.withtypeversion:
+ # it does not make sense to cache this type, it changes bases
+ w_type.version_tag = None
saved_bases = w_type.bases_w
saved_base = w_type.w_bestbase
From cfbolz at codespeak.net Wed Jan 10 16:03:30 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 16:03:30 +0100 (CET)
Subject: [pypy-svn] r36408 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20070110150330.2A4C910064@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 16:03:29 2007
New Revision: 36408
Modified:
pypy/dist/pypy/objspace/std/test/test_versionedtype.py
pypy/dist/pypy/objspace/std/typeobject.py
Log:
(pedronis, cfbolz): don't give a version tag to builtin types that have a dict.
Modified: pypy/dist/pypy/objspace/std/test/test_versionedtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_versionedtype.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_versionedtype.py Wed Jan 10 16:03:29 2007
@@ -64,6 +64,19 @@
""")
assert w_B.version_tag is None
+ def test_version_tag_of_builtin_types(self):
+ space = self.space
+ assert space.w_list.version_tag is not None
+ assert space.w_dict.version_tag is not None
+ assert space.type(space.sys).version_tag is None
+ assert space.w_type.version_tag is None
+ w_function = space.appexec([], """():
+ def f():
+ pass
+ return type(f)
+ """)
+ assert w_function.version_tag is None
+
class AppTestVersionedType(test_typeobject.AppTestTypeObject):
def setup_class(cls):
Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py (original)
+++ pypy/dist/pypy/objspace/std/typeobject.py Wed Jan 10 16:03:29 2007
@@ -213,7 +213,10 @@
return
w_self.mro_w = w_self.compute_mro()
if space.config.objspace.std.withtypeversion:
- w_self.version_tag = VersionTag()
+ if overridetypedef is not None and w_self.hasdict:
+ w_self.version_tag = None
+ else:
+ w_self.version_tag = VersionTag()
def mutated(w_self):
space = w_self.space
From cfbolz at codespeak.net Wed Jan 10 16:16:18 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 16:16:18 +0100 (CET)
Subject: [pypy-svn] r36409 - in pypy/dist/pypy/objspace/std: . test
Message-ID: <20070110151618.D6AC210064@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 16:16:17 2007
New Revision: 36409
Modified:
pypy/dist/pypy/objspace/std/test/test_versionedtype.py
pypy/dist/pypy/objspace/std/typeobject.py
Log:
(pedronis, cfbolz): also do the right thing when you subclass such types.
Modified: pypy/dist/pypy/objspace/std/test/test_versionedtype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_versionedtype.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_versionedtype.py Wed Jan 10 16:16:17 2007
@@ -77,6 +77,33 @@
""")
assert w_function.version_tag is None
+ def test_version_tag_of_subclasses_of_builtin_types(self):
+ space = self.space
+ w_types = space.appexec([], """():
+ import sys
+ class LIST(list):
+ def f(self): pass
+ class DICT(dict):
+ pass
+ class TYPE(type):
+ pass
+ class MODULE(type(sys)):
+ pass
+ def f(x): pass
+ class FUNCTION(type(f)):
+ pass
+ class OBJECT(object):
+ pass
+ return [LIST, DICT, TYPE, MODULE, FUNCTION, OBJECT]
+ """)
+ (w_LIST, w_DICT, w_TYPE, w_MODULE, w_FUNCTION,
+ w_OBJECT) = space.unpackiterable(w_types)
+ assert w_LIST.version_tag is not None
+ assert w_DICT.version_tag is not None
+ assert w_TYPE.version_tag is None
+ assert w_MODULE.version_tag is None
+ assert w_FUNCTION.version_tag is None
+ assert w_OBJECT.version_tag is not None
class AppTestVersionedType(test_typeobject.AppTestTypeObject):
def setup_class(cls):
Modified: pypy/dist/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/typeobject.py (original)
+++ pypy/dist/pypy/objspace/std/typeobject.py Wed Jan 10 16:16:17 2007
@@ -213,7 +213,7 @@
return
w_self.mro_w = w_self.compute_mro()
if space.config.objspace.std.withtypeversion:
- if overridetypedef is not None and w_self.hasdict:
+ if w_self.instancetypedef.hasdict:
w_self.version_tag = None
else:
w_self.version_tag = VersionTag()
From arigo at codespeak.net Wed Jan 10 16:18:57 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 10 Jan 2007 16:18:57 +0100 (CET)
Subject: [pypy-svn] r36410 - pypy/dist/pypy/translator/tool/pygame
Message-ID: <20070110151857.A879F10072@code0.codespeak.net>
Author: arigo
Date: Wed Jan 10 16:18:56 2007
New Revision: 36410
Modified:
pypy/dist/pypy/translator/tool/pygame/graphdisplay.py
Log:
Adapt the initial ANIM_STEP to machines that are faster than my old laptop.
Modified: pypy/dist/pypy/translator/tool/pygame/graphdisplay.py
==============================================================================
--- pypy/dist/pypy/translator/tool/pygame/graphdisplay.py (original)
+++ pypy/dist/pypy/translator/tool/pygame/graphdisplay.py Wed Jan 10 16:18:56 2007
@@ -60,7 +60,7 @@
class GraphDisplay(Display):
STATUSBARFONT = FIXEDFONT
- ANIM_STEP = 0.07
+ ANIM_STEP = 0.03
KEY_REPEAT = (500, 30)
STATUSBAR_ALPHA = 0.75
STATUSBAR_FGCOLOR = (255, 255, 80)
From arigo at codespeak.net Wed Jan 10 16:20:45 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 10 Jan 2007 16:20:45 +0100 (CET)
Subject: [pypy-svn] r36411 - pypy/dist/pypy/translator/goal
Message-ID: <20070110152045.3642F10064@code0.codespeak.net>
Author: arigo
Date: Wed Jan 10 16:20:42 2007
New Revision: 36411
Modified:
pypy/dist/pypy/translator/goal/app_main.py
Log:
(Janzert)
signal.SIGPIPE does not exist on Windows.
Modified: pypy/dist/pypy/translator/goal/app_main.py
==============================================================================
--- pypy/dist/pypy/translator/goal/app_main.py (original)
+++ pypy/dist/pypy/translator/goal/app_main.py Wed Jan 10 16:20:42 2007
@@ -222,7 +222,8 @@
pass
else:
signal.signal(signal.SIGINT, signal.default_int_handler)
- signal.signal(signal.SIGPIPE, signal.SIG_IGN)
+ if hasattr(signal, "SIGPIPE"):
+ signal.signal(signal.SIGPIPE, signal.SIG_IGN)
try:
if sys.argv:
From arigo at codespeak.net Wed Jan 10 16:36:37 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 10 Jan 2007 16:36:37 +0100 (CET)
Subject: [pypy-svn] r36412 - pypy/branch/i386-regalloc
Message-ID: <20070110153637.30F731007A@code0.codespeak.net>
Author: arigo
Date: Wed Jan 10 16:36:35 2007
New Revision: 36412
Added:
pypy/branch/i386-regalloc/
- copied from r36411, pypy/dist/
Log:
A branch to try out a naive backwards register allocator for the i386 codegen.
From arigo at codespeak.net Wed Jan 10 16:38:51 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 10 Jan 2007 16:38:51 +0100 (CET)
Subject: [pypy-svn] r36413 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070110153851.93C461007A@code0.codespeak.net>
Author: arigo
Date: Wed Jan 10 16:38:50 2007
New Revision: 36413
Added:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Early stuff.
Added: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- (empty file)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Wed Jan 10 16:38:50 2007
@@ -0,0 +1,290 @@
+from pypy.rlib.objectmodel import specialize
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
+from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
+from pypy.jit.codegen.i386 import ri386
+from pypy.jit.codegen.i386.ri386 import I386CodeBuilder
+
+
+WORD = 4 # bytes
+
+
+class Operation(GenVar):
+ def allocate_registers(self, allocator):
+ pass
+ def generate(self, allocator):
+ raise NotImplementedError
+
+class Op1(Operation):
+ def __init__(self, x):
+ self.x = x
+ def allocate_registers(self, allocator):
+ allocator.using(self.x)
+ def generate(self, allocator):
+ operand = allocator.var2loc[self]
+ allocator.load_operand(operand, self.x)
+ self.emit(allocator.mc, operand)
+
+class OpSameAs(Op1):
+ emit = staticmethod(lambda mc, x: None)
+
+class Op2(Operation):
+ def __init__(self, x, y):
+ self.x = x
+ self.y = y
+ def allocate_registers(self, allocator):
+ allocator.using(self.x)
+ allocator.using(self.y)
+ def generate(self, allocator):
+ operand1 = allocator.var2loc[self]
+ allocator.load_operand(operand1, self.x)
+ operand2 = allocator.get_location(self.y)
+ self.emit(allocator.mc, operand1, operand2)
+
+class OpIntAdd(Op2):
+ opname = 'int_add'
+ emit = staticmethod(I386CodeBuilder.ADD)
+
+class OpIntSub(Op2):
+ opname = 'int_sub'
+ emit = staticmethod(I386CodeBuilder.SUB)
+
+
+class InputVar(GenVar):
+ def __init__(self, operand):
+ self.operand = operand
+
+class IntConst(GenConst):
+ def __init__(self, value):
+ self.value = value
+
+
+def setup_opclasses(base):
+ d = {}
+ for name, value in globals().items():
+ if type(value) is type(base) and issubclass(value, base):
+ if hasattr(value, 'opname'):
+ assert value.opname not in d
+ d[value.opname] = value
+ return d
+OPCLASSES1 = setup_opclasses(Op1)
+OPCLASSES2 = setup_opclasses(Op2)
+del setup_opclasses
+
+
+class RegAllocator(object):
+ AVAILABLE_REGS = [ri386.eax, ri386.ecx, ri386.edx,
+ ri386.ebx, ri386.esi, ri386.edi]
+ AVAILABLE_REGS.reverse()
+
+ def __init__(self, operations):
+ self.operations = operations
+ self.var2loc = {}
+
+ def set_final(self, final_vars, final_locs):
+ used = {}
+ for i in range(len(final_vars)):
+ v = final_vars[i]
+ loc = final_locs[i]
+ if v.is_const or v in self.var2loc or (
+ isinstance(v, InputVar) and v.operand != loc):
+ v = OpSameAs(v)
+ self.operations.append(v)
+ self.var2loc[v] = loc
+ used[loc] = True
+ self.available_regs = [reg for reg in self.AVAILABLE_REGS
+ if reg not in used]
+
+ def creating(self, v):
+ loc = self.var2loc.get(v, None)
+ if isinstance(loc, ri386.REG):
+ self.available_regs.append(loc)
+
+ def using(self, v):
+ if not v.is_const and v not in self.var2loc:
+ if isinstance(v, InputVar):
+ loc = v.operand
+ else:
+ try:
+ loc = self.available_regs.pop()
+ except IndexError:
+ #loc = ...
+ raise NotImplementedError
+ self.var2loc[v] = loc
+
+ def get_location(self, gv_source):
+ if isinstance(gv_source, IntConst):
+ return ri386.imm(gv_source.value)
+ else:
+ return self.var2loc[gv_source]
+
+ def load_operand(self, operand, gv_source):
+ srcloc = self.get_location(gv_source)
+ if srcloc != operand:
+ self.mc.MOV(operand, srcloc)
+
+
+class Builder(GenBuilder):
+
+ def __init__(self, rgenop, inputargs_gv):
+ self.rgenop = rgenop
+ self.inputargs_gv = inputargs_gv
+
+ def start_writing(self):
+ self.operations = []
+
+ def generate_block_code(self, final_vars, final_locs):
+ allocator = RegAllocator(self.operations)
+ allocator.set_final(final_vars, final_locs)
+ for i in range(len(operations)-1, -1, -1):
+ v = operations[i]
+ allocator.creating(v)
+ v.allocate_registers(allocator)
+ allocator.mc = self.rgenop.open_mc()
+ for op in operations:
+ op.generate(allocator)
+
+ def finish_and_return(self, sigtoken, gv_returnvar):
+ mc = self.generate_block_code([gv_returnvar], [ri386.eax])
+ mc.RET()
+ self.close_mc(mc)
+
+ @specialize.arg(1)
+ def genop1(self, opname, gv_arg):
+ cls = OPCLASSES1[opname]
+ return cls(gv_arg)
+
+ @specialize.arg(1)
+ def genop2(self, opname, gv_arg1, gv_arg2):
+ cls = OPCLASSES2[opname]
+ return cls(gv_arg1, gv_arg2)
+
+
+class RI386GenOp(AbstractRGenOp):
+ from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
+ from pypy.jit.codegen.i386.codebuf import InMemoryCodeBuilder
+
+ MC_SIZE = 65536
+
+ def __init__(self):
+ self.mcs = [] # machine code blocks where no-one is currently writing
+ self.keepalive_gc_refs = []
+ self.total_code_blocks = 0
+
+ def open_mc(self):
+ if self.mcs:
+ # XXX think about inserting NOPS for alignment
+ return self.mcs.pop()
+ else:
+ # XXX supposed infinite for now
+ self.total_code_blocks += 1
+ return self.MachineCodeBlock(self.MC_SIZE)
+
+ def close_mc(self, mc):
+ # an open 'mc' is ready for receiving code... but it's also ready
+ # for being garbage collected, so be sure to close it if you
+ # want the generated code to stay around :-)
+ self.mcs.append(mc)
+
+ def check_no_open_mc(self):
+ assert len(self.mcs) == self.total_code_blocks
+
+ def newgraph(self, sigtoken, name):
+ numargs = sigtoken # for now
+ inputargs_gv = [InputVar(ri386.mem(ri386.EBP, WORD * (2+i)))
+ for i in range(numargs)]
+ builder = Builder(self, inputargs_gv)
+ builder.start_writing()
+ builder.operations.append(prologue)
+ builder.generate_block_code(
+ ...
+ entrypoint = builder.mc.tell()
+ return builder, IntConst(entrypoint), inputargs_gv
+
+ def replay(self, label, kinds):
+ return ReplayBuilder(self), [dummy_var] * len(kinds)
+
+ @specialize.genconst(1)
+ def genconst(self, llvalue):
+ T = lltype.typeOf(llvalue)
+ if T is llmemory.Address:
+ return AddrConst(llvalue)
+ elif isinstance(T, lltype.Primitive):
+ return IntConst(lltype.cast_primitive(lltype.Signed, llvalue))
+ elif isinstance(T, lltype.Ptr):
+ lladdr = llmemory.cast_ptr_to_adr(llvalue)
+ if T.TO._gckind == 'gc':
+ self.keepalive_gc_refs.append(lltype.cast_opaque_ptr(llmemory.GCREF, llvalue))
+ return AddrConst(lladdr)
+ else:
+ assert 0, "XXX not implemented"
+
+ # attached later constPrebuiltGlobal = global_rgenop.genconst
+
+ @staticmethod
+ @specialize.memo()
+ def fieldToken(T, name):
+ FIELD = getattr(T, name)
+ if isinstance(FIELD, lltype.ContainerType):
+ fieldsize = 0 # not useful for getsubstruct
+ else:
+ fieldsize = llmemory.sizeof(FIELD)
+ return (llmemory.offsetof(T, name), fieldsize)
+
+ @staticmethod
+ @specialize.memo()
+ def allocToken(T):
+ return llmemory.sizeof(T)
+
+ @staticmethod
+ @specialize.memo()
+ def varsizeAllocToken(T):
+ if isinstance(T, lltype.Array):
+ return RI386GenOp.arrayToken(T)
+ else:
+ # var-sized structs
+ arrayfield = T._arrayfld
+ ARRAYFIELD = getattr(T, arrayfield)
+ arraytoken = RI386GenOp.arrayToken(ARRAYFIELD)
+ length_offset, items_offset, item_size = arraytoken
+ arrayfield_offset = llmemory.offsetof(T, arrayfield)
+ return (arrayfield_offset+length_offset,
+ arrayfield_offset+items_offset,
+ item_size)
+
+ @staticmethod
+ @specialize.memo()
+ def arrayToken(A):
+ return (llmemory.ArrayLengthOffset(A),
+ llmemory.ArrayItemsOffset(A),
+ llmemory.ItemOffset(A.OF))
+
+ @staticmethod
+ @specialize.memo()
+ def kindToken(T):
+ if T is lltype.Float:
+ py.test.skip("not implemented: floats in the i386 back-end")
+ return None # for now
+
+ @staticmethod
+ @specialize.memo()
+ def sigToken(FUNCTYPE):
+ numargs = 0
+ for ARG in FUNCTYPE.ARGS:
+ if ARG is not lltype.Void:
+ numargs += 1
+ return numargs # for now
+
+ @staticmethod
+ def erasedType(T):
+ if T is llmemory.Address:
+ return llmemory.Address
+ if isinstance(T, lltype.Primitive):
+ return lltype.Signed
+ elif isinstance(T, lltype.Ptr):
+ return llmemory.GCREF
+ else:
+ assert 0, "XXX not implemented"
+
+global_rgenop = RI386GenOp()
+RI386GenOp.constPrebuiltGlobal = global_rgenop.genconst
From cfbolz at codespeak.net Wed Jan 10 16:57:42 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 16:57:42 +0100 (CET)
Subject: [pypy-svn] r36414 - pypy/dist/pypy/config
Message-ID: <20070110155742.6E6271007D@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 16:57:42 2007
New Revision: 36414
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
hm, not a completely good plan to make signal a default module.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Wed Jan 10 16:57:42 2007
@@ -14,14 +14,14 @@
default_modules = essential_modules.copy()
default_modules.update(dict.fromkeys(
["_codecs", "gc", "_weakref", "array", "marshal", "errno",
- "math", "_sre", "_pickle_support", "signal",
+ "math", "_sre", "_pickle_support",
"recparser", "symbol", "_random", "pypymagic"]))
working_modules = default_modules.copy()
working_modules.update(dict.fromkeys(
["rsocket", "unicodedata", "mmap", "fcntl", "rctime", "select", "bz2",
- "crypt",
+ "crypt", "signal",
]
))
From fijal at codespeak.net Wed Jan 10 17:01:09 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 17:01:09 +0100 (CET)
Subject: [pypy-svn] r36415 - in pypy/dist/pypy/translator/js: . test
Message-ID: <20070110160109.96ECF1007D@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 17:01:06 2007
New Revision: 36415
Added:
pypy/dist/pypy/translator/js/test/test_rclass.py
- copied, changed from r36186, pypy/dist/pypy/translator/js/test/test_rpython.py
Removed:
pypy/dist/pypy/translator/js/test/test_rpython.py
Modified:
pypy/dist/pypy/translator/js/_class.py
pypy/dist/pypy/translator/js/asmgen.py
pypy/dist/pypy/translator/js/database.py
pypy/dist/pypy/translator/js/function.py
pypy/dist/pypy/translator/js/js.py
pypy/dist/pypy/translator/js/jts.py
pypy/dist/pypy/translator/js/test/runtest.py
pypy/dist/pypy/translator/js/test/test_runtest.py
pypy/dist/pypy/translator/js/test/test_typed.py
Log:
Removed deprecated files.
--Ta linia i nast?pne zostan? zignorowane--
D modules/test/test_xmlhttp.py
D modules/xmlhttp.py
D modules/bltns.py
Modified: pypy/dist/pypy/translator/js/_class.py
==============================================================================
--- pypy/dist/pypy/translator/js/_class.py (original)
+++ pypy/dist/pypy/translator/js/_class.py Wed Jan 10 17:01:06 2007
@@ -65,7 +65,8 @@
ilasm.inherits(self.name, basename)
for m_name, m_meth in self.classdef._methods.iteritems():
- f = self.db.genoo.Function(self.db, m_meth.graph, m_name, is_method = True, _class = self.name)
+ graph = getattr(m_meth, 'graph', None)
+ f = self.db.genoo.Function(self.db, graph, m_name, is_method = True, _class = self.name)
f.render(ilasm)
self.db.record_class(self.classdef, self.name)
Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py (original)
+++ pypy/dist/pypy/translator/js/asmgen.py Wed Jan 10 17:01:06 2007
@@ -226,7 +226,7 @@
def begin_consts(self, name):
# load consts, maybe more try to use stack-based features?
self.codegenerator.writeline("%s = {};"%name)
-
+
def new_obj(self):
self.right_hand.append("{}")
@@ -249,6 +249,9 @@
def load_void(self):
self.right_hand.append("undefined")
+
+ def load_void_obj(self):
+ self.right_hand.append("{}")
def begin_try(self):
self.codegenerator.write("try ")
Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py (original)
+++ pypy/dist/pypy/translator/js/database.py Wed Jan 10 17:01:06 2007
@@ -6,7 +6,6 @@
from pypy.translator.js.opcodes import opcodes
from pypy.translator.js.function import Function
from pypy.translator.js.log import log
-from pypy.translator.js.jts import JTS
from pypy.translator.js._class import Class
from pypy.translator.js.support import JavascriptNameManager
@@ -124,18 +123,20 @@
else:
return const
- def gen_constants(self, ilasm):
- if not self.rendered:
- ilasm.begin_consts(self.const_var.name)
-
+ def gen_constants(self, ilasm, pending):
try:
while True:
const,name = self.pending_consts.pop()
const.record_fields()
except IndexError:
pass
-
+ if pending:
+ return
+
+ if not self.rendered:
+ ilasm.begin_consts(self.const_var.name)
+
def generate_constants(consts):
all_c = [const for const,name in consts.iteritems()]
dep_ok = set()
@@ -162,15 +163,18 @@
log("Consts: %r"%self.consts)
# We need to keep track of fields to make sure
# our items appear earlier than us
- for const,name in generate_constants(self.consts):
+ to_init = []
+ for const, name in generate_constants(self.consts):
log("Recording %r %r"%(const,name))
ilasm.load_local(self.const_var)
const.init(ilasm)
ilasm.set_field(None, name)
ilasm.store_void()
- const.init_fields(ilasm, self.const_var, name)
+ to_init.append((const, name))
#ilasm.field(name, const.get_type(), static=True)
-
+ for const, name in to_init:
+ const.init_fields(ilasm, self.const_var, name)
+
def load_const(self, type_, value, ilasm):
if self.is_primitive(type_):
ilasm.load_const(self.cts.primitive_repr(type_, value))
Modified: pypy/dist/pypy/translator/js/function.py
==============================================================================
--- pypy/dist/pypy/translator/js/function.py (original)
+++ pypy/dist/pypy/translator/js/function.py Wed Jan 10 17:01:06 2007
@@ -19,42 +19,6 @@
import re
-class LoopFinder(object):
-
- def __init__(self, startblock):
- self.loops = {}
- self.parents = {startblock: startblock}
- self.temps = {}
- self.seen = set ()
- self.block_seeing_order = {}
- self.visit_Block(startblock)
-
- def visit_Block(self, block, switches=[]):
- #self.temps.has_key()
- self.seen.add(block)
- self.block_seeing_order[block] = []
- if block.exitswitch:
- switches.append(block)
- self.parents[block] = block
- for link in block.exits:
- self.block_seeing_order[block].append(link)
- self.visit_Link(link, switches)
-
- def visit_Link(self, link, switches):
- if link.target in switches:
- #if self.loops.has_key(link.target):
- # # double loop
- # pass
- block_switch = self.block_seeing_order[link.target]
- if len(self.block_seeing_order[link.target]) == 1:
- self.loops[(block_switch[0].exitcase,link.target)] = block_switch[0].exitcase
- else:
- self.loops[(block_switch[1].exitcase,link.target)] = block_switch[1].exitcase
-
- if not link.target in self.seen:
- self.parents[link.target] = self.parents[link.prevblock]
- self.visit_Block(link.target, switches)
-
class Function(Node, Generator):
def __init__(self, db, graph, name=None, is_method=False, is_entrypoint=False, _class = None):
self.db = db
Modified: pypy/dist/pypy/translator/js/js.py
==============================================================================
--- pypy/dist/pypy/translator/js/js.py (original)
+++ pypy/dist/pypy/translator/js/js.py Wed Jan 10 17:01:06 2007
@@ -99,7 +99,7 @@
self.gen_entrypoint()
while self.db._pending_nodes:
self.gen_pendings()
- self.db.gen_constants(self.ilasm)
+ self.db.gen_constants(self.ilasm, self.db._pending_nodes)
self.ilasm.close()
return self.tmpfile.strpath
Modified: pypy/dist/pypy/translator/js/jts.py
==============================================================================
--- pypy/dist/pypy/translator/js/jts.py (original)
+++ pypy/dist/pypy/translator/js/jts.py Wed Jan 10 17:01:06 2007
@@ -67,13 +67,11 @@
# TODO: use callvirt only when strictly necessary
if isinstance(obj, ootype.Instance):
owner, meth = obj._lookup(name)
- class_name = obj._name
- return self.graph_to_signature(meth.graph, True, class_name)
-
+ METH = meth._TYPE
+ return obj._name, METH.ARGS
elif isinstance(obj, ootype.BuiltinType):
meth = oopspec.get_method(obj, name)
class_name = self.lltype_to_cts(obj)
- #arg_list = ', '.join(arg_types)
return class_name,meth.ARGS
else:
assert False
@@ -105,6 +103,8 @@
elif _type is UniChar or _type is Char:
#log("Constant %r"%v)
s = repr(v)
+ if s.startswith('u'):
+ s = s[1:]
if s != "'\''":
s.replace("'", '"')
val = s
Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py (original)
+++ pypy/dist/pypy/translator/js/test/runtest.py Wed Jan 10 17:01:06 2007
@@ -1,5 +1,4 @@
'''
- Skipped tests should still be fixed. (or only run with py.test --browser)
Sests with DONT in front of them will probably not be fixed for the time being.
'''
@@ -109,6 +108,11 @@
for s in output.split('\n'):
log(s)
+ return self.reinterpret(s)
+
+ def reinterpret(cls, s):
+ while s.startswith(" "):
+ s = s[1:] # :-) quite inneficient, but who cares
if s == 'false':
res = False
elif s == 'true':
@@ -121,13 +125,16 @@
res = (1e300 * 1e300) / (1e300 * 1e300)
elif s.startswith("uncaught exception:"):
raise LLException(str(s))
+ elif s.startswith('[') or s.startswith('('):
+ l = s[1:-1].split(',')
+ res = [cls.reinterpret(i) for i in l]
else:
- log('javascript result:', s)
try:
- res = eval(s)
- except:
+ res = float(s)
+ except ValueError:
res = str(s)
return res
+ reinterpret = classmethod(reinterpret)
class JsTest(BaseRtypingTest, OORtypeMixin):
#def __init__(self):
@@ -143,7 +150,7 @@
# self._func = fn
# self._ann = ann
# self._cli_func = compile_function(fn, ann)
- # return self._cli_func
+ # return self._cli_func
source = py.code.Source("""
def %s():
from pypy.rlib.nonconst import NonConstant
Modified: pypy/dist/pypy/translator/js/test/test_runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_runtest.py (original)
+++ pypy/dist/pypy/translator/js/test/test_runtest.py Wed Jan 10 17:01:06 2007
@@ -51,6 +51,11 @@
assert f(False, 13, 12.5) == combined_params(False, 13, 12.5)
assert f(True , 13, 12.5) == combined_params(True , 13, 12.5)
+def test_return_function():
+ rp = compile_function.reinterpret
+ assert rp('[a,b]') == ["a", "b"]
+ #assert rp('(true,[a,b])') == [True, ["a", "b"]]
+
##def test_multiple_function():
## def one():
## return 1
Modified: pypy/dist/pypy/translator/js/test/test_typed.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_typed.py (original)
+++ pypy/dist/pypy/translator/js/test/test_typed.py Wed Jan 10 17:01:06 2007
@@ -172,7 +172,7 @@
assert res == testfn(i, j)
def test_unichr_eq():
- py.test.skip("Unicode support")
+ #py.test.skip("Unicode support")
l = list(u'Hello world')
def f(i, j):
return l[i] == l[j]
@@ -183,7 +183,7 @@
assert res == f(i,j)
def test_unichr_ne():
- py.test.skip("Unicode support")
+ #py.test.skip("Unicode support")
l = list(u'Hello world')
def f(i, j):
return l[i] != l[j]
@@ -195,7 +195,7 @@
def test_unichr_ord():
#py.test.skip("ord semantics")
- py.test.skip("Unicode support")
+ #py.test.skip("Unicode support")
l = list(u'Hello world')
def f(i):
return ord(l[i])
@@ -205,7 +205,7 @@
assert res == f(i)
def test_unichr_unichr():
- py.test.skip("Unicode support")
+ #py.test.skip("Unicode support")
l = list(u'Hello world')
def f(i, j):
return l[i] == unichr(j)
From mwh at codespeak.net Wed Jan 10 17:17:09 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Wed, 10 Jan 2007 17:17:09 +0100 (CET)
Subject: [pypy-svn] r36416 - in pypy/dist/pypy/jit/codegen: ppc test
Message-ID: <20070110161709.A254D10070@code0.codespeak.net>
Author: mwh
Date: Wed Jan 10 17:17:07 2007
New Revision: 36416
Modified:
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
fix at least some of the test_genc_ts failures on ppc - i wasn't clearing the
list of pseudo instructions when doing register allocation in pause_writing(),
which lead to some instructions being emitted twice and general confusion.
add an assert that would have caught this, and a test that would also have
caught it.
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Wed Jan 10 17:17:07 2007
@@ -287,6 +287,7 @@
self.crf = allocator.loc_of(self.reg_args[0])
self.bit, self.negated = allocator.crfinfo[self.crf.number]
+ assert self.targetbuilder.initial_var2loc is None
self.targetbuilder.initial_var2loc = {}
for gv_arg in self.jump_args_gv:
self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Wed Jan 10 17:17:07 2007
@@ -1,6 +1,7 @@
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lloperation
from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.jit.codegen.ppc.conftest import option
from ctypes import POINTER, cast, c_void_p, c_int
@@ -205,13 +206,19 @@
@specialize.arg(1)
def genop1(self, opname, gv_arg):
+ #print opname, 'on', id(self)
genmethod = getattr(self, 'op_' + opname)
- return genmethod(gv_arg)
+ r = genmethod(gv_arg)
+ #print '->', id(r)
+ return r
@specialize.arg(1)
def genop2(self, opname, gv_arg1, gv_arg2):
+ #print opname, 'on', id(self)
genmethod = getattr(self, 'op_' + opname)
- return genmethod(gv_arg1, gv_arg2)
+ r = genmethod(gv_arg1, gv_arg2)
+ #print '->', id(r)
+ return r
def genop_call(self, sigtoken, gv_fnptr, args_gv):
self.insns.append(insn.SpillCalleeSaves())
@@ -322,8 +329,14 @@
## def genop_debug_pdb(self): # may take an args_gv later
def enter_next_block(self, kinds, args_gv):
+ #print 'enter_next_block of', id(self)
vars_gv = [v for v in args_gv if isinstance(v, Var)]
+ #print 'initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
+ #print 'initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
var2loc = self.allocate_and_emit(vars_gv).var2loc
+ #print 'var2loc.keys():', [id(v) for v in var2loc.keys()]
+ #print 'var2loc.values():', [id(v) for v in var2loc.values()]
+ #print 'args_gv', [id(v) for v in args_gv]
#print "enter_next_block:", args_gv, var2loc
@@ -333,6 +346,11 @@
for gv in args_gv:
if isinstance(gv, Var):
assert gv in var2loc
+## if gv not in var2loc:
+## lloperation.llop.debug_print(lltype.Void, gv)
+## lloperation.llop.debug_print(lltype.Void, var2loc)
+## lloperation.llop.debug_print(lltype.Void, args_gv)
+## lloperation.llop.debug_pdb(lltype.Void)
loc = var2loc[gv]
livevar2loc[gv] = loc
if not loc.is_register:
@@ -362,13 +380,19 @@
self.insns = []
self.initial_var2loc = livevar2loc
+ #print 'final initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
+ #print 'final initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
self.initial_spill_offset = min_stack_offset
target_addr = self.asm.mc.tell()
self.emit_stack_adjustment()
return Label(target_addr, arg_locations, min_stack_offset)
def jump_if_false(self, gv_condition, args_gv):
- return self._jump(gv_condition, False, args_gv)
+ #print 'jump_if_false', [id(v) for v in args_gv]
+ #print id(self)
+ t = self._jump(gv_condition, False, args_gv)
+ #print '->', id(t)
+ return t
def jump_if_true(self, gv_condition, args_gv):
return self._jump(gv_condition, True, args_gv)
@@ -444,14 +468,15 @@
self.patch_start_here = 0
def pause_writing(self, args_gv):
- self.allocate_and_emit(args_gv)
+ self.initial_var2loc = self.allocate_and_emit(args_gv).var2loc
+ self.insns = []
self.final_jump_addr = self.asm.mc.tell()
self.asm.nop()
self.asm.nop()
self.asm.mtctr(rSCRATCH)
self.asm.bctr()
self._close()
- return self
+ return self
# ----------------------------------------------------------------
# ppc-specific interface:
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Wed Jan 10 17:17:07 2007
@@ -332,6 +332,42 @@
return res
return fact_runner
+def make_func_calling_pause(rgenop):
+ # def f(x):
+ # if x > 0:
+ # return x
+ # else:
+ # return -x
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "abs")
+
+ gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(0))
+
+ targetbuilder = builder.jump_if_false(gv_cond, [gv_x])
+
+ builder = builder.pause_writing([gv_x])
+
+ targetbuilder.start_writing()
+ gv_negated = targetbuilder.genop1("int_neg", gv_x)
+ targetbuilder.finish_and_return(sigtoken, gv_negated)
+
+ builder.start_writing()
+ builder.finish_and_return(sigtoken, gv_x)
+
+ return gv_f
+
+def get_func_calling_pause_runner(RGenOp):
+ def runner(x):
+ rgenop = RGenOp()
+ gv_abs = make_func_calling_pause(rgenop)
+ myabs = gv_abs.revealconst(lltype.Ptr(FUNC))
+ res = myabs(x)
+ keepalive_until_here(rgenop) # to keep the code blocks alive
+ return res
+ return runner
+
+
class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
RGenOp = None
@@ -515,3 +551,18 @@
res = fn(11)
assert res == 39916800
+ def test_calling_pause_direct(self):
+ rgenop = self.RGenOp()
+ gv_abs = make_func_calling_pause(rgenop)
+ fnptr = self.cast(gv_abs, 1)
+ res = fnptr(2)
+ assert res == 2
+ res = fnptr(-42)
+ assert res == 42
+
+ def test_calling_pause_compile(self):
+ fn = self.compile(get_func_calling_pause_runner(self.RGenOp), [int])
+ res = fn(2)
+ assert res == 2
+ res = fn(-72)
+ assert res == 72
From fijal at codespeak.net Wed Jan 10 17:26:23 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 17:26:23 +0100 (CET)
Subject: [pypy-svn] r36417 - pypy/dist/pypy/doc/js
Message-ID: <20070110162623.C41881007D@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 17:26:22 2007
New Revision: 36417
Added:
pypy/dist/pypy/doc/js/todo.txt
Log:
Added.
Added: pypy/dist/pypy/doc/js/todo.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/js/todo.txt Wed Jan 10 17:26:22 2007
@@ -0,0 +1,16 @@
+Some todo list
+--------------
+
+* Complete the test coverage (rclass, rlist and friends)
+
+* Make a tutorial somewhat usable
+
+* External function interface should be refined
+
+* Optimizations
+
+ - names usage
+
+ - empty/trivial blocks
+
+ - unnecessary jumps
From arigo at codespeak.net Wed Jan 10 18:49:09 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 10 Jan 2007 18:49:09 +0100 (CET)
Subject: [pypy-svn] r36419 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070110174909.E3D4D10078@code0.codespeak.net>
Author: arigo
Date: Wed Jan 10 18:49:07 2007
New Revision: 36419
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/conftest.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
Log:
Intermediate check-in before I change many things again (because the
current approach doesn't work).
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/conftest.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/conftest.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/conftest.py Wed Jan 10 18:49:07 2007
@@ -14,3 +14,11 @@
py.test.skip('detected a %r CPU' % (processor,))
return super(Directory, self).run()
+
+Option = py.test.Config.Option
+
+option = py.test.Config.addoptions("ppc options",
+ Option('--trap', action="store_true", default=False,
+ dest="trap",
+ help=""),
+ )
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Wed Jan 10 18:49:07 2007
@@ -2,8 +2,8 @@
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
-from pypy.jit.codegen.i386 import ri386
-from pypy.jit.codegen.i386.ri386 import I386CodeBuilder
+from pypy.jit.codegen.i386.ri386 import *
+from pypy.jit.codegen.i386 import conftest
WORD = 4 # bytes
@@ -49,15 +49,70 @@
opname = 'int_sub'
emit = staticmethod(I386CodeBuilder.SUB)
-
-class InputVar(GenVar):
- def __init__(self, operand):
- self.operand = operand
+# ____________________________________________________________
class IntConst(GenConst):
+
def __init__(self, value):
self.value = value
+ def operand(self, builder):
+ return imm(self.value)
+
+ def nonimmoperand(self, builder, tmpregister):
+ builder.mc.MOV(tmpregister, self.operand(builder))
+ return tmpregister
+
+ @specialize.arg(1)
+ def revealconst(self, T):
+ if isinstance(T, lltype.Ptr):
+ return lltype.cast_int_to_ptr(T, self.value)
+ elif T is llmemory.Address:
+ return llmemory.cast_int_to_adr(self.value)
+ else:
+ return lltype.cast_primitive(T, self.value)
+
+ def __repr__(self):
+ "NOT_RPYTHON"
+ try:
+ return "const=%s" % (imm(self.value).assembler(),)
+ except TypeError: # from Symbolics
+ return "const=%r" % (self.value,)
+
+ def repr(self):
+ return "const=$%s" % (self.value,)
+
+class AddrConst(GenConst):
+
+ def __init__(self, addr):
+ self.addr = addr
+
+ def operand(self, builder):
+ return imm(llmemory.cast_adr_to_int(self.addr))
+
+ def nonimmoperand(self, builder, tmpregister):
+ builder.mc.MOV(tmpregister, self.operand(builder))
+ return tmpregister
+
+ @specialize.arg(1)
+ def revealconst(self, T):
+ if T is llmemory.Address:
+ return self.addr
+ elif isinstance(T, lltype.Ptr):
+ return llmemory.cast_adr_to_ptr(self.addr, T)
+ elif T is lltype.Signed:
+ return llmemory.cast_adr_to_int(self.addr)
+ else:
+ assert 0, "XXX not implemented"
+
+ def __repr__(self):
+ "NOT_RPYTHON"
+ return "const=%r" % (self.addr,)
+
+ def repr(self):
+ return "const=<0x%x>" % (llmemory.cast_adr_to_int(self.addr),)
+
+# ____________________________________________________________
def setup_opclasses(base):
d = {}
@@ -73,38 +128,39 @@
class RegAllocator(object):
- AVAILABLE_REGS = [ri386.eax, ri386.ecx, ri386.edx,
- ri386.ebx, ri386.esi, ri386.edi]
- AVAILABLE_REGS.reverse()
+ AVAILABLE_REGS = [eax, ecx, edx, ebx, esi, edi]
+ AVAILABLE_REGS_REV = AVAILABLE_REGS[:]
+ AVAILABLE_REGS_REV.reverse()
- def __init__(self, operations):
+ def __init__(self, operations, input_var2loc):
self.operations = operations
+ self.input_var2loc = input_var2loc
self.var2loc = {}
- def set_final(self, final_vars, final_locs):
+ def set_final(self, final_vars_gv, final_locs):
used = {}
- for i in range(len(final_vars)):
- v = final_vars[i]
+ for i in range(len(final_vars_gv)):
+ v = final_vars_gv[i]
loc = final_locs[i]
if v.is_const or v in self.var2loc or (
- isinstance(v, InputVar) and v.operand != loc):
+ self.input_var2loc.get(v, loc) != loc):
v = OpSameAs(v)
self.operations.append(v)
self.var2loc[v] = loc
used[loc] = True
- self.available_regs = [reg for reg in self.AVAILABLE_REGS
+ self.available_regs = [reg for reg in self.AVAILABLE_REGS_REV
if reg not in used]
def creating(self, v):
loc = self.var2loc.get(v, None)
- if isinstance(loc, ri386.REG):
+ if isinstance(loc, REG):
self.available_regs.append(loc)
def using(self, v):
if not v.is_const and v not in self.var2loc:
- if isinstance(v, InputVar):
- loc = v.operand
- else:
+ try:
+ loc = self.input_var2loc[v]
+ except KeyError:
try:
loc = self.available_regs.pop()
except IndexError:
@@ -114,7 +170,7 @@
def get_location(self, gv_source):
if isinstance(gv_source, IntConst):
- return ri386.imm(gv_source.value)
+ return imm(gv_source.value)
else:
return self.var2loc[gv_source]
@@ -125,39 +181,106 @@
class Builder(GenBuilder):
+ coming_from = 0
- def __init__(self, rgenop, inputargs_gv):
+ def __init__(self, rgenop, input_vars_gv, input_var2loc):
self.rgenop = rgenop
- self.inputargs_gv = inputargs_gv
+ self.input_vars_gv = input_vars_gv
+ self.input_var2loc = input_var2loc
def start_writing(self):
self.operations = []
- def generate_block_code(self, final_vars, final_locs):
- allocator = RegAllocator(self.operations)
- allocator.set_final(final_vars, final_locs)
+ def generate_block_code(self, final_vars_gv, final_locs):
+ operations = self.operations
+ allocator = RegAllocator(operations, self.input_var2loc)
+ allocator.set_final(final_vars_gv, final_locs)
for i in range(len(operations)-1, -1, -1):
v = operations[i]
allocator.creating(v)
v.allocate_registers(allocator)
- allocator.mc = self.rgenop.open_mc()
+ mc = self.start_mc()
+ allocator.mc = mc
for op in operations:
op.generate(allocator)
+ self.operations = None
+ return mc
+
+ def enter_next_block(self, kinds, args_gv):
+ locs = {}
+ seen_regs = 0
+ for v in args_gv:
+ loc = self.input_var2loc.get(v, None)
+ locs[v] = loc
+ if isinstance(loc, REG):
+ i = loc.op
+ seen_regs |= 1 << i
+ i = 0
+ final_locs = []
+ final_var2loc = {}
+ for v in args_gv:
+ loc = locs[v]
+ if loc is None:
+ while seen_regs & (1 << i):
+ i += 1
+ assert i < len(RegAllocator.AVAILABLE_REGS) # XXX
+ loc = RegAllocator.AVAILABLE_REGS[i]
+ i += 1
+ final_locs.append(loc)
+ final_var2loc[v] = loc
+ mc = self.generate_block_code(args_gv, final_locs)
+ self.set_coming_from(mc)
+ self.rgenop.close_mc(mc)
+ self.input_args_gv = args_gv
+ self.input_var2loc = final_var2loc
+ self.start_writing()
+
+ def set_coming_from(self, mc, insn=I386CodeBuilder.JMP):
+ self.coming_from_insn = insn
+ self.coming_from = mc.tell()
+ insn(mc, rel32(0))
+
+ def start_mc(self):
+ mc = self.rgenop.open_mc()
+ # update the coming_from instruction
+ start = self.coming_from
+ if start:
+ targetaddr = mc.tell()
+ end = start + 6 # XXX hard-coded, enough for JMP and Jcond
+ oldmc = self.rgenop.InMemoryCodeBuilder(start, end)
+ insn = self.coming_from_insn
+ insn(oldmc, rel32(targetaddr))
+ oldmc.done()
+ self.coming_from = 0
+ return mc
def finish_and_return(self, sigtoken, gv_returnvar):
- mc = self.generate_block_code([gv_returnvar], [ri386.eax])
+ mc = self.generate_block_code([gv_returnvar], [eax])
+ # --- epilogue ---
+ mc.POP(edi)
+ mc.POP(esi)
+ mc.POP(ebx)
+ mc.POP(ebp)
mc.RET()
- self.close_mc(mc)
+ # ----------------
+ self.rgenop.close_mc(mc)
+
+ def end(self):
+ pass
@specialize.arg(1)
def genop1(self, opname, gv_arg):
cls = OPCLASSES1[opname]
- return cls(gv_arg)
+ op = cls(gv_arg)
+ self.operations.append(op)
+ return op
@specialize.arg(1)
def genop2(self, opname, gv_arg1, gv_arg2):
cls = OPCLASSES2[opname]
- return cls(gv_arg1, gv_arg2)
+ op = cls(gv_arg1, gv_arg2)
+ self.operations.append(op)
+ return op
class RI386GenOp(AbstractRGenOp):
@@ -190,19 +313,33 @@
assert len(self.mcs) == self.total_code_blocks
def newgraph(self, sigtoken, name):
+ # --- prologue ---
+ mc = self.open_mc()
+ entrypoint = mc.tell()
+ if conftest.option.trap:
+ mc.BREAKPOINT()
+ mc.PUSH(ebp)
+ mc.MOV(ebp, esp)
+ mc.PUSH(ebx)
+ mc.PUSH(esi)
+ mc.PUSH(edi)
+ self.close_mc(mc)
+ # NB. a bit of a hack: the first generated block of the function
+ # will immediately follow, by construction
+ # ----------------
numargs = sigtoken # for now
- inputargs_gv = [InputVar(ri386.mem(ri386.EBP, WORD * (2+i)))
- for i in range(numargs)]
- builder = Builder(self, inputargs_gv)
+ inputargs_gv = []
+ input_var2loc = {}
+ for i in range(numargs):
+ v = GenVar()
+ inputargs_gv.append(v)
+ input_var2loc[v] = mem(ebp, WORD * (2+i))
+ builder = Builder(self, inputargs_gv, input_var2loc)
builder.start_writing()
- builder.operations.append(prologue)
- builder.generate_block_code(
- ...
- entrypoint = builder.mc.tell()
return builder, IntConst(entrypoint), inputargs_gv
- def replay(self, label, kinds):
- return ReplayBuilder(self), [dummy_var] * len(kinds)
+## def replay(self, label, kinds):
+## return ReplayBuilder(self), [dummy_var] * len(kinds)
@specialize.genconst(1)
def genconst(self, llvalue):
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py Wed Jan 10 18:49:07 2007
@@ -6,11 +6,15 @@
class REG(OPERAND):
width = 4
+ def __repr__(self):
+ return '<%s>' % self.__class__.__name__.lower()
def assembler(self):
return '%' + self.__class__.__name__.lower()
class REG8(OPERAND):
width = 1
+ def __repr__(self):
+ return '<%s>' % self.__class__.__name__.lower()
def assembler(self):
return '%' + self.__class__.__name__.lower()
From fijal at codespeak.net Wed Jan 10 18:50:04 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 18:50:04 +0100 (CET)
Subject: [pypy-svn] r36420 - pypy/dist/pypy/doc/js
Message-ID: <20070110175004.90F351007C@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 18:50:02 2007
New Revision: 36420
Modified:
pypy/dist/pypy/doc/js/todo.txt
Log:
new paragrpah
Modified: pypy/dist/pypy/doc/js/todo.txt
==============================================================================
--- pypy/dist/pypy/doc/js/todo.txt (original)
+++ pypy/dist/pypy/doc/js/todo.txt Wed Jan 10 18:50:02 2007
@@ -14,3 +14,5 @@
- empty/trivial blocks
- unnecessary jumps
+
+* Provide some high level widgets-like functionality
\ No newline at end of file
From antocuni at codespeak.net Wed Jan 10 18:59:16 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Wed, 10 Jan 2007 18:59:16 +0100 (CET)
Subject: [pypy-svn] r36421 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070110175916.3FB7610078@code0.codespeak.net>
Author: antocuni
Date: Wed Jan 10 18:59:09 2007
New Revision: 36421
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
Log:
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt Wed Jan 10 18:59:09 2007
@@ -3,7 +3,7 @@
Samuele Pedroni -10 -8
Michael Hudson -10 -8
Niko Matsakis
-Antonio Cuni -10 -8
+Antonio Cuni -10 -8 +8
Maciej Fijalkowski -10 -8 +110
Eric van Riet Paap
Jacob Hallen -10 -8
From ericvrp at codespeak.net Wed Jan 10 18:59:56 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Wed, 10 Jan 2007 18:59:56 +0100 (CET)
Subject: [pypy-svn] r36422 - in pypy/dist/pypy/translator/llvm: . test
Message-ID: <20070110175956.A455F10080@code0.codespeak.net>
Author: ericvrp
Date: Wed Jan 10 18:59:50 2007
New Revision: 36422
Modified:
pypy/dist/pypy/translator/llvm/buildllvm.py
pypy/dist/pypy/translator/llvm/externs2ll.py
pypy/dist/pypy/translator/llvm/gc.py
pypy/dist/pypy/translator/llvm/test/test_seq.py
Log:
try to support both llvm-gcc 3 and 4
Modified: pypy/dist/pypy/translator/llvm/buildllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/buildllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/buildllvm.py Wed Jan 10 18:59:50 2007
@@ -21,6 +21,13 @@
v = int(v) / 10.0
return v
+def llvm_gcc_version():
+ v = os.popen('llvm-gcc --version 2>&1').read()
+ i = v.index(')')
+ v = v[i+2:].split()[0].split('.')
+ v = float(v[0]) + float(v[1]) / 10.0
+ return v
+
def optimizations(simple, use_gcc):
if simple:
Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py (original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py Wed Jan 10 18:59:50 2007
@@ -7,9 +7,12 @@
from pypy.rpython.rmodel import inputconst
from pypy.rpython.lltypesystem import lltype
from pypy.translator.llvm.codewriter import DEFAULT_CCONV
+from pypy.translator.llvm.buildllvm import llvm_gcc_version
from pypy.tool.udir import udir
+_llvm_gcc_version = None
+
support_functions = [
"%raisePyExc_IOError",
"%raisePyExc_ValueError",
@@ -36,9 +39,17 @@
plain = filename[:-2]
includes = get_incdirs()
- cmd = "llvm-gcc %s -S %s.c -o %s.ll 2>&1" % (includes,
- plain,
- plain)
+
+ global _llvm_gcc_version
+ if not _llvm_gcc_version:
+ _llvm_gcc_version = llvm_gcc_version()
+ if _llvm_gcc_version < 4.0:
+ emit_llvm = ''
+ else:
+ emit_llvm = '-emit-llvm'
+ cmd = "llvm-gcc %s %s -S %s.c -o %s.ll 2>&1" % (
+ includes, emit_llvm, plain, plain)
+
os.system(cmd)
llcode = open(plain + '.ll').read()
Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py (original)
+++ pypy/dist/pypy/translator/llvm/gc.py Wed Jan 10 18:59:50 2007
@@ -158,7 +158,7 @@
class BoehmGcPolicy(GcPolicy):
- def __init__(self, db, exc_useringbuf=True):
+ def __init__(self, db, exc_useringbuf=False):
self.db = db
# XXX a config option...
self.exc_useringbuf = exc_useringbuf
Modified: pypy/dist/pypy/translator/llvm/test/test_seq.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_seq.py (original)
+++ pypy/dist/pypy/translator/llvm/test/test_seq.py Wed Jan 10 18:59:50 2007
@@ -7,6 +7,21 @@
from pypy.translator.llvm.test.runtest import *
class TestLLVMArray(object):
+ def test_char_array(self):
+ from pypy.rpython.lltypesystem import lltype
+ A = lltype.GcArray(lltype.Char)
+ def fn(n):
+ a = lltype.malloc(A, 5)
+ a[4] = 'H'
+ a[3] = 'e'
+ a[2] = 'l'
+ a[1] = 'l'
+ a[0] = 'o'
+ return ord(a[n])
+ fp = compile_function(fn, [int])
+ for i in range(5):
+ assert fp(i) == fn(i)
+
def test_array(self):
f = compile_function(llvmsnippet.array_simple, [])
assert f() == 42
From fijal at codespeak.net Wed Jan 10 19:07:22 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 19:07:22 +0100 (CET)
Subject: [pypy-svn] r36423 - in pypy/dist/pypy/translator: cl lisp
Message-ID: <20070110180722.5B03910078@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 19:07:20 2007
New Revision: 36423
Added:
pypy/dist/pypy/translator/lisp/
- copied from r36186, pypy/dist/pypy/translator/cl/
Removed:
pypy/dist/pypy/translator/cl/
Log:
Moved cl -> lisp not to confuse cl
From fijal at codespeak.net Wed Jan 10 19:11:51 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 19:11:51 +0100 (CET)
Subject: [pypy-svn] r36424 - in pypy/dist/pypy/translator/lisp: . test
Message-ID: <20070110181151.59DD01007E@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 19:11:31 2007
New Revision: 36424
Modified:
pypy/dist/pypy/translator/lisp/buildcl.py
pypy/dist/pypy/translator/lisp/gencl.py
pypy/dist/pypy/translator/lisp/opformatter.py
pypy/dist/pypy/translator/lisp/test/test_call.py
pypy/dist/pypy/translator/lisp/test/test_clrepr.py
pypy/dist/pypy/translator/lisp/test/test_cltrans.py
pypy/dist/pypy/translator/lisp/test/test_dict.py
pypy/dist/pypy/translator/lisp/test/test_exception.py
pypy/dist/pypy/translator/lisp/test/test_list.py
pypy/dist/pypy/translator/lisp/test/test_oo.py
pypy/dist/pypy/translator/lisp/test/test_tuple.py
Log:
s/cl/lisp/g
Modified: pypy/dist/pypy/translator/lisp/buildcl.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/buildcl.py (original)
+++ pypy/dist/pypy/translator/lisp/buildcl.py Wed Jan 10 19:11:31 2007
@@ -3,10 +3,10 @@
from pypy.tool.udir import udir
from pypy.translator.translator import TranslationContext
-from pypy.translator.cl.gencl import GenCL
-from pypy.translator.cl.clrepr import clrepr
+from pypy.translator.lisp.gencl import GenCL
+from pypy.translator.lisp.clrepr import clrepr
from pypy import conftest
-from pypy.translator.cl import conftest as clconftest
+from pypy.translator.lisp import conftest as clconftest
global_cl = None
Modified: pypy/dist/pypy/translator/lisp/gencl.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/gencl.py (original)
+++ pypy/dist/pypy/translator/lisp/gencl.py Wed Jan 10 19:11:31 2007
@@ -5,8 +5,8 @@
from pypy.translator.translator import graphof
from pypy.rpython.ootypesystem.ootype import dynamicType, oodowncast, null, Record, Instance, _class, _static_meth, _meth, ROOT
from pypy.rpython.ootypesystem.rclass import OBJECT
-from pypy.translator.cl.clrepr import clrepr
-from pypy.translator.cl.opformatter import OpFormatter
+from pypy.translator.lisp.clrepr import clrepr
+from pypy.translator.lisp.opformatter import OpFormatter
class InsertionOrderedDict(dict):
def __init__(self):
Modified: pypy/dist/pypy/translator/lisp/opformatter.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/opformatter.py (original)
+++ pypy/dist/pypy/translator/lisp/opformatter.py Wed Jan 10 19:11:31 2007
@@ -1,6 +1,6 @@
from pypy.rpython.ootypesystem.ootype import List, Dict, Record, Instance
from pypy.rpython.ootypesystem.ootype import DictItemsIterator
-from pypy.translator.cl.clrepr import clrepr
+from pypy.translator.lisp.clrepr import clrepr
class OpFormatter:
Modified: pypy/dist/pypy/translator/lisp/test/test_call.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_call.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_call.py Wed Jan 10 19:11:31 2007
@@ -1,5 +1,5 @@
import py
-from pypy.translator.cl.buildcl import make_cl_func
+from pypy.translator.lisp.buildcl import make_cl_func
def test_call():
def add_one(n):
Modified: pypy/dist/pypy/translator/lisp/test/test_clrepr.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_clrepr.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_clrepr.py Wed Jan 10 19:11:31 2007
@@ -1,5 +1,5 @@
import py
-from pypy.translator.cl.clrepr import clrepr
+from pypy.translator.lisp.clrepr import clrepr
def test_const():
assert clrepr(True) == 't'
Modified: pypy/dist/pypy/translator/lisp/test/test_cltrans.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_cltrans.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_cltrans.py Wed Jan 10 19:11:31 2007
@@ -3,7 +3,7 @@
import os
from pypy.annotation.model import SomeChar
-from pypy.translator.cl.buildcl import make_cl_func
+from pypy.translator.lisp.buildcl import make_cl_func
from pypy.translator.test import snippet as t
Modified: pypy/dist/pypy/translator/lisp/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_dict.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_dict.py Wed Jan 10 19:11:31 2007
@@ -1,5 +1,5 @@
import py
-from pypy.translator.cl.buildcl import make_cl_func
+from pypy.translator.lisp.buildcl import make_cl_func
def test_dict_length():
def dict_length_one(key, val):
Modified: pypy/dist/pypy/translator/lisp/test/test_exception.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_exception.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_exception.py Wed Jan 10 19:11:31 2007
@@ -1,5 +1,5 @@
import py
-from pypy.translator.cl.buildcl import make_cl_func
+from pypy.translator.lisp.buildcl import make_cl_func
def test_handle_exception():
py.test.skip("We support exceptions, but not really it seems")
Modified: pypy/dist/pypy/translator/lisp/test/test_list.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_list.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_list.py Wed Jan 10 19:11:31 2007
@@ -1,4 +1,4 @@
-from pypy.translator.cl.buildcl import make_cl_func
+from pypy.translator.lisp.buildcl import make_cl_func
from py.test import skip
def sum_(l):
Modified: pypy/dist/pypy/translator/lisp/test/test_oo.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_oo.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_oo.py Wed Jan 10 19:11:31 2007
@@ -1,5 +1,5 @@
import py
-from pypy.translator.cl.buildcl import make_cl_func, generate_cl_code
+from pypy.translator.lisp.buildcl import make_cl_func, generate_cl_code
def test_simple():
class C:
Modified: pypy/dist/pypy/translator/lisp/test/test_tuple.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/test/test_tuple.py (original)
+++ pypy/dist/pypy/translator/lisp/test/test_tuple.py Wed Jan 10 19:11:31 2007
@@ -1,4 +1,4 @@
-from pypy.translator.cl.buildcl import make_cl_func
+from pypy.translator.lisp.buildcl import make_cl_func
from py.test import skip
def test_tuple_get():
From fijal at codespeak.net Wed Jan 10 19:12:58 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 19:12:58 +0100 (CET)
Subject: [pypy-svn] r36425 - pypy/dist/pypy/translator
Message-ID: <20070110181258.11DAB10088@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 19:12:47 2007
New Revision: 36425
Modified:
pypy/dist/pypy/translator/driver.py
Log:
s/cl/lisp/
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Wed Jan 10 19:12:47 2007
@@ -508,7 +508,7 @@
idemp=True)
def task_source_cl(self):
- from pypy.translator.cl.gencl import GenCL
+ from pypy.translator.lisp.gencl import GenCL
self.gen = GenCL(self.translator, self.entry_point)
filename = self.gen.emitfile()
self.log.info("Wrote %s" % (filename,))
From ericvrp at codespeak.net Wed Jan 10 19:22:39 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Wed, 10 Jan 2007 19:22:39 +0100 (CET)
Subject: [pypy-svn] r36427 - pypy/dist/pypy/translator/llvm
Message-ID: <20070110182239.CF21910080@code0.codespeak.net>
Author: ericvrp
Date: Wed Jan 10 19:22:37 2007
New Revision: 36427
Modified:
pypy/dist/pypy/translator/llvm/buildllvm.py
pypy/dist/pypy/translator/llvm/gc.py
Log:
argh, didn't mean to check in the gc policy change.
arg(2) llvm-gcc version info syntax differs.
Modified: pypy/dist/pypy/translator/llvm/buildllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/buildllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/buildllvm.py Wed Jan 10 19:22:37 2007
@@ -25,7 +25,8 @@
v = os.popen('llvm-gcc --version 2>&1').read()
i = v.index(')')
v = v[i+2:].split()[0].split('.')
- v = float(v[0]) + float(v[1]) / 10.0
+ major, minor = v[0], ''.join([c for c in v[1] if c.isdigit()])
+ v = float(major) + float(minor) / 10.0
return v
def optimizations(simple, use_gcc):
Modified: pypy/dist/pypy/translator/llvm/gc.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/gc.py (original)
+++ pypy/dist/pypy/translator/llvm/gc.py Wed Jan 10 19:22:37 2007
@@ -158,7 +158,7 @@
class BoehmGcPolicy(GcPolicy):
- def __init__(self, db, exc_useringbuf=False):
+ def __init__(self, db, exc_useringbuf=True):
self.db = db
# XXX a config option...
self.exc_useringbuf = exc_useringbuf
From cfbolz at codespeak.net Wed Jan 10 19:41:18 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 19:41:18 +0100 (CET)
Subject: [pypy-svn] r36429 - in pypy/dist/pypy: interpreter objspace
objspace/std
Message-ID: <20070110184118.863DF10078@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 19:41:16 2007
New Revision: 36429
Modified:
pypy/dist/pypy/interpreter/baseobjspace.py
pypy/dist/pypy/objspace/descroperation.py
pypy/dist/pypy/objspace/std/dictmultiobject.py
pypy/dist/pypy/objspace/std/dictobject.py
pypy/dist/pypy/objspace/std/dictstrobject.py
pypy/dist/pypy/objspace/std/objspace.py
pypy/dist/pypy/objspace/std/proxyobject.py
Log:
(pedronis, cfbolz): make it possible to track shadowing of type attributes by
instances. only preparation, nothing much working.
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Jan 10 19:41:16 2007
@@ -27,10 +27,10 @@
return space.finditem(w_dict, w_attr)
return None
- def setdictvalue(self, space, w_attr, w_value):
+ def setdictvalue(self, space, w_attr, w_value, shadows_type=True):
w_dict = self.getdict()
if w_dict is not None:
- space.set_str_keyed_item(w_dict, w_attr, w_value)
+ space.set_str_keyed_item(w_dict, w_attr, w_value, shadows_type)
return True
return False
@@ -434,7 +434,7 @@
"""shortcut for space.int_w(space.hash(w_obj))"""
return self.int_w(self.hash(w_obj))
- def set_str_keyed_item(self, w_obj, w_key, w_value):
+ def set_str_keyed_item(self, w_obj, w_key, w_value, shadows_type=True):
return self.setitem(w_obj, w_key, w_value)
def finditem(self, w_obj, w_key):
Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py (original)
+++ pypy/dist/pypy/objspace/descroperation.py Wed Jan 10 19:41:16 2007
@@ -31,11 +31,13 @@
def descr__setattr__(space, w_obj, w_name, w_value):
name = space.str_w(w_name)
w_descr = space.lookup(w_obj, name)
+ shadows_type = False
if w_descr is not None:
if space.is_data_descr(w_descr):
space.set(w_descr, w_obj, w_value)
return
- if w_obj.setdictvalue(space, w_name, w_value):
+ shadows_type = True
+ if w_obj.setdictvalue(space, w_name, w_value, shadows_type):
return
raiseattrerror(space, w_obj, name, w_descr)
Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/dist/pypy/objspace/std/dictmultiobject.py Wed Jan 10 19:41:16 2007
@@ -41,7 +41,7 @@
## def get(self, w_lookup):
## return w_value or None
-## def setitem_str(self, w_key, w_value):
+## def setitem_str(self, w_key, w_value, shadows_type=True):
## return implementation
## def setitem(self, w_key, w_value):
## return implementation
@@ -142,7 +142,7 @@
else:
return RDictImplementation(self.space).setitem(w_key, w_value)
#return SmallDictImplementation(self.space, w_key, w_value)
- def setitem_str(self, w_key, w_value):
+ def setitem_str(self, w_key, w_value, shadows_type=True):
return StrDictImplementation(self.space).setitem_str(w_key, w_value)
#return SmallStrDictImplementation(self.space, w_key, w_value)
def delitem(self, w_key):
@@ -221,7 +221,8 @@
entry.w_value = w_value
return self
- setitem_str = setitem
+ def setitem_str(self, w_key, w_value, shadows_type=True):
+ return self.setitem(w_key, w_value)
def delitem(self, w_key):
entry = self._lookup(w_key)
@@ -321,7 +322,7 @@
return self._convert_to_rdict().setitem(w_key, w_value)
return self.setitem_str(w_key, w_value)
- def setitem_str(self, w_key, w_value):
+ def setitem_str(self, w_key, w_value, shadows_type=True):
entry = self._lookup(self.space.str_w(w_key))
if entry.w_value is None:
if self.valid == 4:
@@ -392,7 +393,7 @@
else:
return self._as_rdict().setitem(w_key, w_value)
- def setitem_str(self, w_key, w_value):
+ def setitem_str(self, w_key, w_value, shadows_type=True):
self.content[self.space.str_w(w_key)] = w_value
return self
@@ -451,7 +452,6 @@
newimpl.setitem(self.space.wrap(k), w_v)
return newimpl
-
# the following are very close copies of the base classes above
class StrKeyIteratorImplementation(IteratorImplementation):
@@ -496,7 +496,7 @@
StrDictImplementation.__init__(self, space)
self.shadowed = [None] * len(BUILTIN_TO_INDEX)
- def setitem_str(self, w_key, w_value):
+ def setitem_str(self, w_key, w_value, shadows_type=True):
key = self.space.str_w(w_key)
i = BUILTIN_TO_INDEX.get(key, -1)
if i != -1:
@@ -533,7 +533,10 @@
def setitem(self, w_key, w_value):
self.content[w_key] = w_value
return self
- setitem_str = setitem
+
+ def setitem_str(self, w_key, w_value, shadows_type=True):
+ return self.setitem(w_key, w_value)
+
def delitem(self, w_key):
del self.content[w_key]
if self.content:
@@ -665,7 +668,7 @@
else:
return self._as_rdict().setitem(w_key, w_value)
- def setitem_str(self, w_key, w_value):
+ def setitem_str(self, w_key, w_value, shadows_type=True):
m = ~len(self.structure.other_structs)
key = self.space.str_w(w_key)
i = self.structure.keys.get(key, m)
@@ -874,7 +877,7 @@
self.content[w_key] = w_value
self.info.maxcontents = max(self.info.maxcontents, len(self.content))
return self
- def setitem_str(self, w_key, w_value):
+ def setitem_str(self, w_key, w_value, shadows_type=True):
self.info.setitem_strs += 1
return self.setitem(w_key, w_value)
def delitem(self, w_key):
@@ -990,8 +993,9 @@
else:
return w_default
- def set_str_keyed_item(w_dict, w_key, w_value):
- w_dict.implementation = w_dict.implementation.setitem_str(w_key, w_value)
+ def set_str_keyed_item(w_dict, w_key, w_value, shadows_type=True):
+ w_dict.implementation = w_dict.implementation.setitem_str(
+ w_key, w_value, shadows_type)
registerimplementation(W_DictMultiObject)
Modified: pypy/dist/pypy/objspace/std/dictobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictobject.py (original)
+++ pypy/dist/pypy/objspace/std/dictobject.py Wed Jan 10 19:41:16 2007
@@ -41,7 +41,7 @@
def get(w_dict, w_lookup, w_default):
return w_dict.content.get(w_lookup, w_default)
- def set_str_keyed_item(w_dict, w_key, w_value):
+ def set_str_keyed_item(w_dict, w_key, w_value, shadows_type=True):
w_dict.content[w_key] = w_value
registerimplementation(W_DictObject)
Modified: pypy/dist/pypy/objspace/std/dictstrobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictstrobject.py (original)
+++ pypy/dist/pypy/objspace/std/dictstrobject.py Wed Jan 10 19:41:16 2007
@@ -53,7 +53,8 @@
w_self.str2object()
w_self.content[w_k] = w_v
- set_str_keyed_item = setitem
+ def set_str_keyed_item(w_self, w_k, w_v, shadows_type=True):
+ return w_self.setitem(w_k, w_v)
def str2object(w_self):
""" Moves all items in the content_str dict to content. """
Modified: pypy/dist/pypy/objspace/std/objspace.py
==============================================================================
--- pypy/dist/pypy/objspace/std/objspace.py (original)
+++ pypy/dist/pypy/objspace/std/objspace.py Wed Jan 10 19:41:16 2007
@@ -511,10 +511,10 @@
return w_obj.get(w_key, None)
return ObjSpace.finditem(self, w_obj, w_key)
- def set_str_keyed_item(self, w_obj, w_key, w_value):
+ def set_str_keyed_item(self, w_obj, w_key, w_value, shadows_type=True):
# performance shortcut to avoid creating the OperationError(KeyError)
if type(w_obj) is self.DictObjectCls:
- w_obj.set_str_keyed_item(w_key, w_value)
+ w_obj.set_str_keyed_item(w_key, w_value, shadows_type)
else:
self.setitem(w_obj, w_key, w_value)
Modified: pypy/dist/pypy/objspace/std/proxyobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/proxyobject.py (original)
+++ pypy/dist/pypy/objspace/std/proxyobject.py Wed Jan 10 19:41:16 2007
@@ -42,7 +42,7 @@
raise
return None
- def setdictvalue(self, space, w_attr, w_value):
+ def setdictvalue(self, space, w_attr, w_value, shadows_type=True):
try:
space.call_function(self.w_controller, space.wrap('__setattr__'),
w_attr, w_value)
From cfbolz at codespeak.net Wed Jan 10 20:06:35 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 20:06:35 +0100 (CET)
Subject: [pypy-svn] r36432 - in pypy/dist/pypy: config interpreter
objspace/std
Message-ID: <20070110190635.9E65C1007C@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 20:06:34 2007
New Revision: 36432
Modified:
pypy/dist/pypy/config/pypyoption.py
pypy/dist/pypy/interpreter/typedef.py
pypy/dist/pypy/objspace/std/dictmultiobject.py
Log:
(pedronis, cfbolz): add "shadow tracking": you can ask an instance whether it
shadows an attribute of a class in the mro.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Wed Jan 10 20:06:34 2007
@@ -145,6 +145,14 @@
cmdline=None,
default=False),
+ BoolOption("withshadowtracking",
+ "track whether an instance attribute shadows a type"
+ " attribute",
+ cmdline=None,
+ default=False,
+ requires=[("objspace.std.withmultidict", True)]),
+
+
BoolOption("optimized_int_add",
"special case the addition of two integers in BINARY_ADD",
default=False),
Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py (original)
+++ pypy/dist/pypy/interpreter/typedef.py Wed Jan 10 20:06:34 2007
@@ -187,6 +187,12 @@
from pypy.objspace.std import dictmultiobject
self.w__dict__ = dictmultiobject.W_DictMultiObject(space,
sharing=True)
+ elif space.config.objspace.std.withshadowtracking:
+ from pypy.objspace.std import dictmultiobject
+ self.w__dict__ = dictmultiobject.W_DictMultiObject(space)
+ self.w__dict__.implementation = \
+ dictmultiobject.ShadowDetectingDictImplementation(
+ space, w_subtype)
else:
self.w__dict__ = space.newdict()
self.user_setup_slots(w_subtype.nslots)
Modified: pypy/dist/pypy/objspace/std/dictmultiobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dictmultiobject.py (original)
+++ pypy/dist/pypy/objspace/std/dictmultiobject.py Wed Jan 10 20:06:34 2007
@@ -94,6 +94,9 @@
w_key = self.space.wrap(OPTIMIZED_BUILTINS[i])
return self.get(w_key)
+# this attribute will only be seen whan a certain config option is used
+ shadows_anything = True
+
# Iterator Implementation base classes
@@ -491,6 +494,30 @@
return None
+class ShadowDetectingDictImplementation(StrDictImplementation):
+ def __init__(self, space, w_type):
+ StrDictImplementation.__init__(self, space)
+ self.w_type = w_type
+ self.shadows_anything = False
+
+ def setitem_str(self, w_key, w_value, shadows_type=True):
+ if shadows_type:
+ self.shadows_anything = True
+ return StrDictImplementation.setitem_str(
+ self, w_key, w_value, shadows_type)
+
+ def setitem(self, w_key, w_value):
+ space = self.space
+ if space.is_w(space.type(w_key), space.w_str):
+ if not self.shadows_anything:
+ w_obj = self.w_type.lookup(space.str_w(w_key))
+ if w_obj is not None:
+ self.shadows_anything = True
+ return StrDictImplementation.setitem_str(
+ self, w_key, w_value, False)
+ else:
+ return self._as_rdict().setitem(w_key, w_value)
+
class WaryDictImplementation(StrDictImplementation):
def __init__(self, space):
StrDictImplementation.__init__(self, space)
From cfbolz at codespeak.net Wed Jan 10 21:56:03 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 21:56:03 +0100 (CET)
Subject: [pypy-svn] r36436 - in pypy/dist/pypy: interpreter objspace/std/test
Message-ID: <20070110205603.6421B10078@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 21:56:02 2007
New Revision: 36436
Added:
pypy/dist/pypy/objspace/std/test/test_shadowtracking.py
Modified:
pypy/dist/pypy/interpreter/typedef.py
Log:
(pedronis, cfbolz): add tests for the last checkin. also give up on shadow
tracking if an instance gets its __class__ changed.
Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py (original)
+++ pypy/dist/pypy/interpreter/typedef.py Wed Jan 10 21:56:02 2007
@@ -196,6 +196,14 @@
else:
self.w__dict__ = space.newdict()
self.user_setup_slots(w_subtype.nslots)
+
+ def setclass(self, space, w_subtype):
+ # only used by descr_set___class__
+ self.w__class__ = w_subtype
+ if space.config.objspace.std.withshadowtracking:
+ self.w__dict__.implementation.shadows_anything = True
+
+
else:
supercls = cls
Added: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Wed Jan 10 21:56:02 2007
@@ -0,0 +1,77 @@
+from pypy.conftest import gettestobjspace
+
+class TestShadowTracking(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withshadowtracking": True})
+
+ def test_simple_shadowing(self):
+ space = self.space
+ w_inst = space.appexec([], """():
+ class A(object):
+ def f(self):
+ return 42
+ a = A()
+ return a
+ """)
+ assert not w_inst.w__dict__.implementation.shadows_anything
+ space.appexec([w_inst], """(a):
+ a.g = "foo"
+ """)
+ assert not w_inst.w__dict__.implementation.shadows_anything
+ space.appexec([w_inst], """(a):
+ a.f = "foo"
+ """)
+ assert w_inst.w__dict__.implementation.shadows_anything
+
+ def test_shadowing_via__dict__(self):
+ space = self.space
+ w_inst = space.appexec([], """():
+ class A(object):
+ def f(self):
+ return 42
+ a = A()
+ return a
+ """)
+ assert not w_inst.w__dict__.implementation.shadows_anything
+ space.appexec([w_inst], """(a):
+ a.__dict__["g"] = "foo"
+ """)
+ assert not w_inst.w__dict__.implementation.shadows_anything
+ space.appexec([w_inst], """(a):
+ a.__dict__["f"] = "foo"
+ """)
+ assert w_inst.w__dict__.implementation.shadows_anything
+
+ def test_changing__dict__(self):
+ space = self.space
+ w_inst = space.appexec([], """():
+ class A(object):
+ def f(self):
+ return 42
+ a = A()
+ return a
+ """)
+ assert not w_inst.w__dict__.implementation.shadows_anything
+ space.appexec([w_inst], """(a):
+ a.__dict__ = {}
+ """)
+ assert w_inst.w__dict__.implementation.shadows_anything
+
+ def test_changing__class__(self):
+ space = self.space
+ w_inst = space.appexec([], """():
+ class A(object):
+ def f(self):
+ return 42
+ a = A()
+ return a
+ """)
+ assert not w_inst.w__dict__.implementation.shadows_anything
+ space.appexec([w_inst], """(a):
+ class B(object):
+ def g(self):
+ return 42
+ a.__class__ = B
+ """)
+ assert w_inst.w__dict__.implementation.shadows_anything
+
From fijal at codespeak.net Wed Jan 10 22:10:16 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 22:10:16 +0100 (CET)
Subject: [pypy-svn] r36437 - pypy/dist/pypy/translator/js/tutorial
Message-ID: <20070110211016.2324C1007E@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 22:10:14 2007
New Revision: 36437
Modified:
pypy/dist/pypy/translator/js/tutorial/step3.py
Log:
make emacs happy
Modified: pypy/dist/pypy/translator/js/tutorial/step3.py
==============================================================================
--- pypy/dist/pypy/translator/js/tutorial/step3.py (original)
+++ pypy/dist/pypy/translator/js/tutorial/step3.py Wed Jan 10 22:10:14 2007
@@ -15,7 +15,7 @@
from pypy.translator.js.modules.dom import document
# dom manipulating module
-HTML = """
+HTML = '''
@@ -29,7 +29,7 @@
Del row
-"""
+'''
# these are exposed functions
def addrow():
From fijal at codespeak.net Wed Jan 10 22:10:40 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 22:10:40 +0100 (CET)
Subject: [pypy-svn] r36438 - pypy/dist/pypy/translator/js/modules
Message-ID: <20070110211040.0A7D510088@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 22:10:38 2007
New Revision: 36438
Modified:
pypy/dist/pypy/translator/js/modules/dom.py
Log:
kill unnecessary comment
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Wed Jan 10 22:10:38 2007
@@ -299,12 +299,10 @@
pass
def setTimeout(func, delay):
- # scheduler call, but we don't want to mess with threads right now
if one():
setTimeout(some_fun, delay)
else:
func()
- #pass
window = Window()
document = window.document
From fijal at codespeak.net Wed Jan 10 22:11:16 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 22:11:16 +0100 (CET)
Subject: [pypy-svn] r36439 - in pypy/dist/pypy/translator/js: . test
Message-ID: <20070110211116.360CE10084@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 22:11:14 2007
New Revision: 36439
Modified:
pypy/dist/pypy/translator/js/_class.py
pypy/dist/pypy/translator/js/database.py
pypy/dist/pypy/translator/js/jts.py
pypy/dist/pypy/translator/js/test/test_rclass.py
Log:
Whack, whack, whack. Another bunch of tests passes, including, but not limited to abstract methods.
Modified: pypy/dist/pypy/translator/js/_class.py
==============================================================================
--- pypy/dist/pypy/translator/js/_class.py (original)
+++ pypy/dist/pypy/translator/js/_class.py Wed Jan 10 22:11:14 2007
@@ -66,8 +66,13 @@
for m_name, m_meth in self.classdef._methods.iteritems():
graph = getattr(m_meth, 'graph', None)
- f = self.db.genoo.Function(self.db, graph, m_name, is_method = True, _class = self.name)
- f.render(ilasm)
+ if graph:
+ f = self.db.genoo.Function(self.db, graph, m_name, is_method = True, _class = self.name)
+ f.render(ilasm)
+ else:
+ pass
+ # XXX: We want to implement an abstract method here
+ self.db.pending_abstract_function(m_name)
self.db.record_class(self.classdef, self.name)
Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py (original)
+++ pypy/dist/pypy/translator/js/database.py Wed Jan 10 22:11:14 2007
@@ -52,6 +52,10 @@
def pending_function(self, graph):
self.pending_node(self.genoo.Function(self, graph))
+ def pending_abstract_function(self, name):
+ pass
+ # XXX we want to implement it at some point (maybe...)
+
def pending_class(self, classdef):
c = Class(self, classdef)
self.pending_node(c)
Modified: pypy/dist/pypy/translator/js/jts.py
==============================================================================
--- pypy/dist/pypy/translator/js/jts.py (original)
+++ pypy/dist/pypy/translator/js/jts.py Wed Jan 10 22:11:14 2007
@@ -98,8 +98,14 @@
# FIXME: It's not ok to use always empty list
val = "[]"
elif isinstance(_type,StaticMethod):
- self.db.pending_function(v.graph)
+ if hasattr(v, 'graph'):
+ self.db.pending_function(v.graph)
+ else:
+ self.db.pending_abstract_function(v)
val = v._name
+ val = val.replace('.', '_')
+ if val == '?':
+ val = 'undefined'
elif _type is UniChar or _type is Char:
#log("Constant %r"%v)
s = repr(v)
Modified: pypy/dist/pypy/translator/js/test/test_rclass.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_rclass.py (original)
+++ pypy/dist/pypy/translator/js/test/test_rclass.py Wed Jan 10 22:11:14 2007
@@ -11,18 +11,61 @@
pass
class TestJsClass(JsTest, BaseTestRclass):
- def test_common_class_attribute(self):
- py.test.skip("WIP")
-
def test___class___attribute(self):
- py.test.skip("unsuitable")
-
+ class Base(object): pass
+ class A(Base): pass
+ class B(Base): pass
+ class C(A): pass
+ def seelater():
+ C()
+ def f(n):
+ if n == 1:
+ x = A()
+ else:
+ x = B()
+ y = B()
+ result = x.__class__, y.__class__
+ seelater()
+ return result
+ def g():
+ cls1, cls2 = f(1)
+ return cls1 is A, cls2 is B
+
+ res = self.interpret(g, [])
+ assert res[0]
+ assert res[1]
+
def test_mixin(self):
- py.test.skip("unsuitable")
-
- def test_getattr_on_classes(self):
- py.test.skip("WIP")
-
+ class Mixin(object):
+ _mixin_ = True
+
+ def m(self, v):
+ return v
+
+ class Base(object):
+ pass
+
+ class A(Base, Mixin):
+ pass
+
+ class B(Base, Mixin):
+ pass
+
+ class C(B):
+ pass
+
+ def f():
+ a = A()
+ v0 = a.m(2)
+ b = B()
+ v1 = b.m('x')
+ c = C()
+ v2 = c.m('y')
+ return v0, v1, v2
+
+ res = self.interpret(f, [])
+ assert isinstance(res[0], float)
+
def test_hash_preservation(self):
py.test.skip("WIP")
@@ -31,9 +74,6 @@
def test_isinstance(self):
py.test.skip("WIP")
-
- def test_recursive_prebuilt_instance_classattr(self):
- py.test.skip("WIP")
#class TestJsList(JsTest, BaseTestRlist):
# def test_insert_bug(self):
From fijal at codespeak.net Wed Jan 10 22:23:48 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Wed, 10 Jan 2007 22:23:48 +0100 (CET)
Subject: [pypy-svn] r36440 - pypy/dist/pypy/translator/js/test
Message-ID: <20070110212348.38C0E10084@code0.codespeak.net>
Author: fijal
Date: Wed Jan 10 22:23:43 2007
New Revision: 36440
Modified:
pypy/dist/pypy/translator/js/test/test_genllvm.py
pypy/dist/pypy/translator/js/test/test_genllvm1.py
pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py
Log:
Unskip tests which passes by now.
Modified: pypy/dist/pypy/translator/js/test/test_genllvm.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_genllvm.py (original)
+++ pypy/dist/pypy/translator/js/test/test_genllvm.py Wed Jan 10 22:23:43 2007
@@ -163,7 +163,6 @@
assert f() == 4
def test_recursive_call():
- py.test.skip("Recursion support is very limited")
def call_ackermann(n, m):
return ackermann(n, m)
def ackermann(n, m):
@@ -358,7 +357,6 @@
assert f() == 4
def test_dict_creation():
- #py.test.skip("Dict support not implemented")
d = {'hello' : 23,
'world' : 21}
l = ["hello", "world"]
@@ -369,8 +367,6 @@
assert f(0,1) == createdict(0,1)
def test_closure():
- #py.test.skip("issue 'null' for Ptr's? or recurse into Ptr.TO?) see: opwriter.py")
- py.test.skip("closure support")
class A:
def set(self, x):
self.x = x
Modified: pypy/dist/pypy/translator/js/test/test_genllvm1.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_genllvm1.py (original)
+++ pypy/dist/pypy/translator/js/test/test_genllvm1.py Wed Jan 10 22:23:43 2007
@@ -26,7 +26,6 @@
assert f(0) == 13
def test_ackermann(self):
- py.test.skip("Too much recursion")
f = compile_function(llvmsnippet.ackermann, [int, int])
for i in range(4): # (otherwise too much recursion) max 4 in Safari, max 7 in Firefox, IE allows more recursion
assert f(0, i) == i + 1
Modified: pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py (original)
+++ pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py Wed Jan 10 22:23:43 2007
@@ -26,7 +26,6 @@
assert basic(i) == merge_if_blocks_basic(i)
def test_merge_if_blocks_chr():
- #py.test.skip("String support in ootypesystem")
def merge_if_blocks_chr(i):
c = chr(i)
if c == '\x05':
@@ -39,7 +38,6 @@
assert basic(i) == merge_if_blocks_chr(i)
def test_merge_if_blocks_uni():
- py.test.skip("Unicode support")
def merge_if_blocks_uni(i):
c = unichr(i)
if c == u'\x05':
From arigo at codespeak.net Wed Jan 10 23:20:03 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Wed, 10 Jan 2007 23:20:03 +0100 (CET)
Subject: [pypy-svn] r36443 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070110222003.97BF710080@code0.codespeak.net>
Author: arigo
Date: Wed Jan 10 23:19:58 2007
New Revision: 36443
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
More work. Register allocator seems to be working, but wack wack wack.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Wed Jan 10 23:19:58 2007
@@ -21,9 +21,12 @@
def allocate_registers(self, allocator):
allocator.using(self.x)
def generate(self, allocator):
- operand = allocator.var2loc[self]
- allocator.load_operand(operand, self.x)
- self.emit(allocator.mc, operand)
+ try:
+ loc = allocator.var2loc[self]
+ except KeyError:
+ return # simple operation whose result is not used anyway
+ op = allocator.load_location_with(loc, self.x)
+ self.emit(allocator.mc, op)
class OpSameAs(Op1):
emit = staticmethod(lambda mc, x: None)
@@ -36,10 +39,13 @@
allocator.using(self.x)
allocator.using(self.y)
def generate(self, allocator):
- operand1 = allocator.var2loc[self]
- allocator.load_operand(operand1, self.x)
- operand2 = allocator.get_location(self.y)
- self.emit(allocator.mc, operand1, operand2)
+ try:
+ loc = allocator.var2loc[self]
+ except KeyError:
+ return # simple operation whose result is not used anyway
+ op1 = allocator.load_location_with(loc, self.x)
+ op2 = allocator.get_operand(self.y)
+ self.emit(allocator.mc, op1, op2)
class OpIntAdd(Op2):
opname = 'int_add'
@@ -126,113 +132,189 @@
OPCLASSES2 = setup_opclasses(Op2)
del setup_opclasses
+OPCLASSES1['int_is_true'] = None
+
+
+class OutOfRegisters(Exception):
+ pass
+
class RegAllocator(object):
AVAILABLE_REGS = [eax, ecx, edx, ebx, esi, edi]
- AVAILABLE_REGS_REV = AVAILABLE_REGS[:]
- AVAILABLE_REGS_REV.reverse()
- def __init__(self, operations, input_var2loc):
- self.operations = operations
- self.input_var2loc = input_var2loc
- self.var2loc = {}
+ # 'gv' -- GenVars, used as arguments and results of operations
+ #
+ # 'loc' -- location, a small integer that represents an abstract
+ # register number
+ #
+ # 'operand' -- a concrete machine code operand, which can be a
+ # register (ri386.eax, etc.) or a stack memory operand
- def set_final(self, final_vars_gv, final_locs):
- used = {}
- for i in range(len(final_vars_gv)):
- v = final_vars_gv[i]
- loc = final_locs[i]
- if v.is_const or v in self.var2loc or (
- self.input_var2loc.get(v, loc) != loc):
- v = OpSameAs(v)
- self.operations.append(v)
- self.var2loc[v] = loc
- used[loc] = True
- self.available_regs = [reg for reg in self.AVAILABLE_REGS_REV
- if reg not in used]
+ def __init__(self):
+ self.nextloc = 0
+ self.var2loc = {}
+ self.available_locs = []
+ self.force_loc2operand = {}
+ self.force_operand2loc = {}
+ self.initial_moves = []
+
+ def set_final(self, final_vars_gv):
+ for v in final_vars_gv:
+ if not v.is_const and v not in self.var2loc:
+ self.var2loc[v] = self.nextloc
+ self.nextloc += 1
def creating(self, v):
- loc = self.var2loc.get(v, None)
- if isinstance(loc, REG):
- self.available_regs.append(loc)
+ try:
+ loc = self.var2loc[v]
+ except KeyError:
+ pass
+ else:
+ self.available_locs.append(loc) # now available again for reuse
def using(self, v):
if not v.is_const and v not in self.var2loc:
try:
- loc = self.input_var2loc[v]
+ loc = self.available_locs.pop()
+ except IndexError:
+ loc = self.nextloc
+ self.nextloc += 1
+ self.var2loc[v] = loc
+
+ def allocate_locations(self, operations):
+ # assign locations to gvars
+ self.operations = operations
+ for i in range(len(operations)-1, -1, -1):
+ v = operations[i]
+ self.creating(v)
+ v.allocate_registers(self)
+
+ def force_var_operands(self, force_vars, force_operands, at_start):
+ force_loc2operand = self.force_loc2operand
+ force_operand2loc = self.force_operand2loc
+ for i in range(len(force_vars)):
+ v = force_vars[i]
+ try:
+ loc = self.var2loc[v]
except KeyError:
+ pass
+ else:
+ operand = force_operands[i]
+ if loc in force_loc2operand or operand in force_operand2loc:
+ if not at_start: raise NotImplementedError
+ self.initial_moves.append((loc, operand))
+ else:
+ force_loc2operand[loc] = operand
+ force_operand2loc[operand] = loc
+
+ def allocate_registers(self):
+ # assign registers to locations that don't have one already
+ force_loc2operand = self.force_loc2operand
+ operands = []
+ seen_regs = 0
+ for op in force_loc2operand.values():
+ if isinstance(op, REG):
+ seen_regs |= 1 << op.op
+ i = 0
+ for loc in range(self.nextloc):
+ try:
+ operand = force_loc2operand[loc]
+ except KeyError:
+ # grab the next free register
+ while seen_regs & (1 << i):
+ i += 1
try:
- loc = self.available_regs.pop()
+ operand = RegAllocator.AVAILABLE_REGS[i]
+ i += 1
except IndexError:
- #loc = ...
- raise NotImplementedError
- self.var2loc[v] = loc
+ raise OutOfRegisters
+ operands.append(operand)
+ self.operands = operands
- def get_location(self, gv_source):
+ def get_operand(self, gv_source):
if isinstance(gv_source, IntConst):
return imm(gv_source.value)
else:
- return self.var2loc[gv_source]
+ loc = self.var2loc[gv_source]
+ return self.operands[loc]
- def load_operand(self, operand, gv_source):
- srcloc = self.get_location(gv_source)
- if srcloc != operand:
- self.mc.MOV(operand, srcloc)
+ def load_location_with(self, loc, gv_source):
+ dstop = self.operands[loc]
+ srcop = self.get_operand(gv_source)
+ if srcop != dstop:
+ self.mc.MOV(dstop, srcop)
+ return dstop
+
+ def generate_initial_moves(self):
+ # XXX naive algo for now
+ initial_moves = self.initial_moves
+ for loc, srcoperand in initial_moves:
+ self.mc.PUSH(srcoperand)
+ initial_moves.reverse()
+ for loc, srcoperand in initial_moves:
+ self.mc.POP(self.operands[loc])
class Builder(GenBuilder):
coming_from = 0
- def __init__(self, rgenop, input_vars_gv, input_var2loc):
+ def __init__(self, rgenop, inputargs_gv, inputoperands):
self.rgenop = rgenop
- self.input_vars_gv = input_vars_gv
- self.input_var2loc = input_var2loc
+ self.inputargs_gv = inputargs_gv
+ self.inputoperands = inputoperands
def start_writing(self):
self.operations = []
- def generate_block_code(self, final_vars_gv, final_locs):
- operations = self.operations
- allocator = RegAllocator(operations, self.input_var2loc)
- allocator.set_final(final_vars_gv, final_locs)
- for i in range(len(operations)-1, -1, -1):
- v = operations[i]
- allocator.creating(v)
- v.allocate_registers(allocator)
+ def generate_block_code(self, final_vars_gv, force_vars=[],
+ force_operands=[]):
+ allocator = RegAllocator()
+ allocator.set_final(final_vars_gv)
+ allocator.allocate_locations(self.operations)
+ allocator.force_var_operands(force_vars, force_operands,
+ at_start=False)
+ #import pdb; pdb.set_trace()
+ allocator.force_var_operands(self.inputargs_gv, self.inputoperands,
+ at_start=True)
+ allocator.allocate_registers()
mc = self.start_mc()
allocator.mc = mc
- for op in operations:
+ allocator.generate_initial_moves()
+ for op in self.operations:
op.generate(allocator)
self.operations = None
+ self.inputargs_gv = [GenVar() for v in final_vars_gv]
+ self.inputoperands = [allocator.operands[allocator.var2loc[v]]
+ for v in final_vars_gv]
return mc
def enter_next_block(self, kinds, args_gv):
- locs = {}
- seen_regs = 0
- for v in args_gv:
- loc = self.input_var2loc.get(v, None)
- locs[v] = loc
- if isinstance(loc, REG):
- i = loc.op
- seen_regs |= 1 << i
- i = 0
- final_locs = []
- final_var2loc = {}
- for v in args_gv:
- loc = locs[v]
- if loc is None:
- while seen_regs & (1 << i):
- i += 1
- assert i < len(RegAllocator.AVAILABLE_REGS) # XXX
- loc = RegAllocator.AVAILABLE_REGS[i]
- i += 1
- final_locs.append(loc)
- final_var2loc[v] = loc
- mc = self.generate_block_code(args_gv, final_locs)
+## locs = {}
+## seen_regs = 0
+## for v in args_gv:
+## loc = self.input_var2loc.get(v, None)
+## locs[v] = loc
+## if isinstance(loc, REG):
+## i = loc.op
+## seen_regs |= 1 << i
+## i = 0
+## final_locs = []
+## final_var2loc = {}
+## for v in args_gv:
+## loc = locs[v]
+## if loc is None:
+## while seen_regs & (1 << i):
+## i += 1
+## assert i < len(RegAllocator.AVAILABLE_REGS) # XXX
+## loc = RegAllocator.AVAILABLE_REGS[i]
+## i += 1
+## final_locs.append(loc)
+## final_var2loc[v] = loc
+
+ mc = self.generate_block_code(args_gv)
+ args_gv[:] = self.inputargs_gv
self.set_coming_from(mc)
self.rgenop.close_mc(mc)
- self.input_args_gv = args_gv
- self.input_var2loc = final_var2loc
self.start_writing()
def set_coming_from(self, mc, insn=I386CodeBuilder.JMP):
@@ -255,7 +337,7 @@
return mc
def finish_and_return(self, sigtoken, gv_returnvar):
- mc = self.generate_block_code([gv_returnvar], [eax])
+ mc = self.generate_block_code([gv_returnvar], [gv_returnvar], [eax])
# --- epilogue ---
mc.POP(edi)
mc.POP(esi)
@@ -271,6 +353,8 @@
@specialize.arg(1)
def genop1(self, opname, gv_arg):
cls = OPCLASSES1[opname]
+ if cls is None: # identity
+ return gv_arg
op = cls(gv_arg)
self.operations.append(op)
return op
@@ -329,13 +413,15 @@
# ----------------
numargs = sigtoken # for now
inputargs_gv = []
- input_var2loc = {}
+ inputoperands = []
for i in range(numargs):
- v = GenVar()
- inputargs_gv.append(v)
- input_var2loc[v] = mem(ebp, WORD * (2+i))
- builder = Builder(self, inputargs_gv, input_var2loc)
+ inputargs_gv.append(GenVar())
+ inputoperands.append(mem(ebp, WORD * (2+i)))
+ builder = Builder(self, inputargs_gv, inputoperands)
builder.start_writing()
+ #ops = [OpSameAs(v) for v in inputargs_gv]
+ #builder.operations.extend(ops)
+ #inputargs_gv = ops
return builder, IntConst(entrypoint), inputargs_gv
## def replay(self, label, kinds):
From cfbolz at codespeak.net Wed Jan 10 23:43:27 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 23:43:27 +0100 (CET)
Subject: [pypy-svn] r36444 - in pypy/dist/pypy: config interpreter objspace
objspace/std/test
Message-ID: <20070110224327.91C9D10084@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 23:43:26 2007
New Revision: 36444
Modified:
pypy/dist/pypy/config/pypyoption.py
pypy/dist/pypy/interpreter/baseobjspace.py
pypy/dist/pypy/interpreter/typedef.py
pypy/dist/pypy/objspace/descroperation.py
pypy/dist/pypy/objspace/std/test/test_shadowtracking.py
Log:
(pedronis, cfbolz): this checkin makes pypy 10-20% faster (if you enable
withshadowtracking). hehe. we avoid the lookup in the instance if the attribute
is on the class and there is no shadowing.
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Wed Jan 10 23:43:26 2007
@@ -148,9 +148,9 @@
BoolOption("withshadowtracking",
"track whether an instance attribute shadows a type"
" attribute",
- cmdline=None,
default=False,
- requires=[("objspace.std.withmultidict", True)]),
+ requires=[("objspace.std.withmultidict", True),
+ ("objspace.std.withtypeversion", True)]),
BoolOption("optimized_int_add",
Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py (original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py Wed Jan 10 23:43:26 2007
@@ -27,6 +27,9 @@
return space.finditem(w_dict, w_attr)
return None
+ def getdictvalue_attr_is_in_class(self, space, w_attr):
+ return self.getdictvalue(space, w_attr)
+
def setdictvalue(self, space, w_attr, w_value, shadows_type=True):
w_dict = self.getdict()
if w_dict is not None:
Modified: pypy/dist/pypy/interpreter/typedef.py
==============================================================================
--- pypy/dist/pypy/interpreter/typedef.py (original)
+++ pypy/dist/pypy/interpreter/typedef.py Wed Jan 10 23:43:26 2007
@@ -178,6 +178,9 @@
if not space.is_true(space.isinstance(w_dict, space.w_dict)):
raise OperationError(space.w_TypeError,
space.wrap("setting dictionary to a non-dict"))
+ if space.config.objspace.std.withmultidict:
+ from pypy.objspace.std import dictmultiobject
+ assert isinstance(w_dict, dictmultiobject.W_DictMultiObject)
self.w__dict__ = w_dict
def user_setup(self, space, w_subtype):
@@ -203,6 +206,13 @@
if space.config.objspace.std.withshadowtracking:
self.w__dict__.implementation.shadows_anything = True
+ def getdictvalue_attr_is_in_class(self, space, w_name):
+ w_dict = self.w__dict__
+ if space.config.objspace.std.withshadowtracking:
+ if (not w_dict.implementation.shadows_anything and
+ self.w__class__.version_tag is not None):
+ return None
+ return space.finditem(w_dict, w_name)
else:
supercls = cls
@@ -213,6 +223,7 @@
return self.w__class__
def setclass(self, space, w_subtype):
+
# only used by descr_set___class__
self.w__class__ = w_subtype
Modified: pypy/dist/pypy/objspace/descroperation.py
==============================================================================
--- pypy/dist/pypy/objspace/descroperation.py (original)
+++ pypy/dist/pypy/objspace/descroperation.py Wed Jan 10 23:43:26 2007
@@ -21,7 +21,9 @@
if w_descr is not None:
if space.is_data_descr(w_descr):
return space.get(w_descr, w_obj)
- w_value = w_obj.getdictvalue(space, w_name)
+ w_value = w_obj.getdictvalue_attr_is_in_class(space, w_name)
+ else:
+ w_value = w_obj.getdictvalue(space, w_name)
if w_value is not None:
return w_value
if w_descr is not None:
Modified: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_shadowtracking.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Wed Jan 10 23:43:26 2007
@@ -75,3 +75,12 @@
""")
assert w_inst.w__dict__.implementation.shadows_anything
+class AppTestShadowTracking(object):
+ def test_shadowtracking_does_not_blow_up(self):
+ class A(object):
+ def f(self):
+ return 42
+ a = A()
+ assert a.f() == 42
+ a.f = lambda : 43
+ assert a.f() == 43
From cfbolz at codespeak.net Wed Jan 10 23:45:32 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Wed, 10 Jan 2007 23:45:32 +0100 (CET)
Subject: [pypy-svn] r36446 - pypy/dist/pypy/config
Message-ID: <20070110224532.57B2D10089@code0.codespeak.net>
Author: cfbolz
Date: Wed Jan 10 23:45:31 2007
New Revision: 36446
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
add shadow tracking to --faassen (mostly to have it be benchmarked tonight on
tuatara).
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Wed Jan 10 23:45:31 2007
@@ -169,6 +169,7 @@
("translation.profopt",
"-c 'from richards import main;main(); from test import pystone; pystone.main()'"),
("objspace.std.withstrjoin", True),
+ ("objspace.std.withshadowtracking", True),
("objspace.std.withstrslice", True),
("objspace.std.withsmallint", True),
("objspace.std.withrangelist", True),
From antocuni at codespeak.net Thu Jan 11 10:15:44 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 11 Jan 2007 10:15:44 +0100 (CET)
Subject: [pypy-svn] r36449 - pypy/dist/pypy/objspace/fake/test
Message-ID: <20070111091544.2778B10080@code0.codespeak.net>
Author: antocuni
Date: Thu Jan 11 10:15:39 2007
New Revision: 36449
Modified:
pypy/dist/pypy/objspace/fake/test/test_checkmodule.py
Log:
skip this test for now.
Modified: pypy/dist/pypy/objspace/fake/test/test_checkmodule.py
==============================================================================
--- pypy/dist/pypy/objspace/fake/test/test_checkmodule.py (original)
+++ pypy/dist/pypy/objspace/fake/test/test_checkmodule.py Thu Jan 11 10:15:39 2007
@@ -3,4 +3,5 @@
def test_dotnet():
# the only module known to pass checkmodule is _dotnet so far
+ py.test.skip('fixme')
checkmodule('_dotnet', 'cli')
From adim at codespeak.net Thu Jan 11 10:34:25 2007
From: adim at codespeak.net (adim at codespeak.net)
Date: Thu, 11 Jan 2007 10:34:25 +0100 (CET)
Subject: [pypy-svn] r36450 -
pypy/branch/ast-experiments/pypy/interpreter/pyparser
Message-ID: <20070111093425.2C20A10082@code0.codespeak.net>
Author: adim
Date: Thu Jan 11 10:34:19 2007
New Revision: 36450
Modified:
pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/asthelper.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfgrammar.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnflexer.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfparse.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/grammar.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonlexer.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonparse.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonutil.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/pytoken.py
pypy/branch/ast-experiments/pypy/interpreter/pyparser/tuplebuilder.py
Log:
use parser's tokens dict and get rid of setattr() usage in pytoken
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/astbuilder.py Thu Jan 11 10:34:19 2007
@@ -46,31 +46,31 @@
top = atoms[0]
if isinstance(top, TokenObject):
# assert isinstance(top, TokenObject) # rtyper
- if top.name == builder.parser.LPAR:
+ if top.name == builder.parser.tokens['LPAR']:
if len(atoms) == 2:
builder.push(ast.Tuple([], top.lineno))
else:
builder.push( atoms[1] )
- elif top.name == builder.parser.LSQB:
+ elif top.name == builder.parser.tokens['LSQB']:
if len(atoms) == 2:
builder.push(ast.List([], top.lineno))
else:
list_node = atoms[1]
list_node.lineno = top.lineno
builder.push(list_node)
- elif top.name == builder.parser.LBRACE:
+ elif top.name == builder.parser.tokens['LBRACE']:
items = []
for index in range(1, len(atoms)-1, 4):
# a : b , c : d
# ^ +1 +2 +3 +4
items.append((atoms[index], atoms[index+2]))
builder.push(ast.Dict(items, top.lineno))
- elif top.name == builder.parser.NAME:
+ elif top.name == builder.parser.tokens['NAME']:
val = top.get_value()
builder.push( ast.Name(val, top.lineno) )
- elif top.name == builder.parser.NUMBER:
+ elif top.name == builder.parser.tokens['NUMBER']:
builder.push(ast.Const(builder.eval_number(top.get_value()), top.lineno))
- elif top.name == builder.parser.STRING:
+ elif top.name == builder.parser.tokens['STRING']:
# need to concatenate strings in atoms
s = ''
if len(atoms) == 1:
@@ -86,7 +86,7 @@
accum.append(parsestr(builder.space, builder.source_encoding, token.get_value()))
w_s = space.call_method(empty, 'join', space.newlist(accum))
builder.push(ast.Const(w_s, top.lineno))
- elif top.name == builder.parser.BACKQUOTE:
+ elif top.name == builder.parser.tokens['BACKQUOTE']:
builder.push(ast.Backquote(atoms[1], atoms[1].lineno))
else:
raise SyntaxError("unexpected tokens", top.lineno, top.col)
@@ -107,7 +107,7 @@
else:
lineno = atoms[0].lineno
token = atoms[-2]
- if isinstance(token, TokenObject) and token.name == builder.parser.DOUBLESTAR:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOUBLESTAR']:
obj = parse_attraccess(slicecut(atoms, 0, -2), builder)
builder.push(ast.Power( obj, atoms[-1], lineno))
else:
@@ -122,11 +122,11 @@
token = atoms[0]
lineno = token.lineno
if isinstance(token, TokenObject):
- if token.name == builder.parser.PLUS:
+ if token.name == builder.parser.tokens['PLUS']:
builder.push( ast.UnaryAdd( atoms[1], lineno) )
- if token.name == builder.parser.MINUS:
+ if token.name == builder.parser.tokens['MINUS']:
builder.push( ast.UnarySub( atoms[1], lineno) )
- if token.name == builder.parser.TILDE:
+ if token.name == builder.parser.tokens['TILDE']:
builder.push( ast.Invert( atoms[1], lineno) )
def build_term(builder, nb):
@@ -137,13 +137,13 @@
right = atoms[i]
op_node = atoms[i-1]
assert isinstance(op_node, TokenObject)
- if op_node.name == builder.parser.STAR:
+ if op_node.name == builder.parser.tokens['STAR']:
left = ast.Mul( left, right, left.lineno )
- elif op_node.name == builder.parser.SLASH:
+ elif op_node.name == builder.parser.tokens['SLASH']:
left = ast.Div( left, right, left.lineno )
- elif op_node.name == builder.parser.PERCENT:
+ elif op_node.name == builder.parser.tokens['PERCENT']:
left = ast.Mod( left, right, left.lineno )
- elif op_node.name == builder.parser.DOUBLESLASH:
+ elif op_node.name == builder.parser.tokens['DOUBLESLASH']:
left = ast.FloorDiv( left, right, left.lineno )
else:
token = atoms[i-1]
@@ -158,9 +158,9 @@
right = atoms[i]
op_node = atoms[i-1]
assert isinstance(op_node, TokenObject)
- if op_node.name == builder.parser.PLUS:
+ if op_node.name == builder.parser.tokens['PLUS']:
left = ast.Add( left, right, left.lineno)
- elif op_node.name == builder.parser.MINUS:
+ elif op_node.name == builder.parser.tokens['MINUS']:
left = ast.Sub( left, right, left.lineno)
else:
token = atoms[i-1]
@@ -176,9 +176,9 @@
right = atoms[i]
op_node = atoms[i-1]
assert isinstance(op_node, TokenObject)
- if op_node.name == builder.parser.LEFTSHIFT:
+ if op_node.name == builder.parser.tokens['LEFTSHIFT']:
left = ast.LeftShift( left, right, lineno )
- elif op_node.name == builder.parser.RIGHTSHIFT:
+ elif op_node.name == builder.parser.tokens['RIGHTSHIFT']:
left = ast.RightShift( left, right, lineno )
else:
token = atoms[i-1]
@@ -255,9 +255,9 @@
lineno = token.lineno
assert isinstance(token, TokenObject)
if token.get_value() == 'not':
- builder.push(TokenObject(builder.parser.NAME, 'not in', lineno, builder.parser))
+ builder.push(TokenObject(builder.parser.tokens['NAME'], 'not in', lineno, builder.parser))
else:
- builder.push(TokenObject(builder.parser.NAME, 'is not', lineno, builder.parser))
+ builder.push(TokenObject(builder.parser.tokens['NAME'], 'is not', lineno, builder.parser))
else:
assert False, "TODO" # uh ?
@@ -309,7 +309,7 @@
return
op = atoms[1]
assert isinstance(op, TokenObject)
- if op.name == builder.parser.EQUAL:
+ if op.name == builder.parser.tokens['EQUAL']:
nodes = []
for i in range(0,l-2,2):
lvalue = to_lvalue(atoms[i], consts.OP_ASSIGN)
@@ -343,7 +343,7 @@
lineno = -1
for n in range(0,l,2):
node = atoms[n]
- if isinstance(node, TokenObject) and node.name == builder.parser.NEWLINE:
+ if isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']:
nodes.append(ast.Discard(ast.Const(builder.wrap_none()), node.lineno))
else:
nodes.append(node)
@@ -369,10 +369,10 @@
for node in atoms:
if isinstance(node, ast.Stmt):
stmts.extend(node.nodes)
- elif isinstance(node, TokenObject) and node.name == builder.parser.ENDMARKER:
+ elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['ENDMARKER']:
# XXX Can't we just remove the last element of the list ?
break
- elif isinstance(node, TokenObject) and node.name == builder.parser.NEWLINE:
+ elif isinstance(node, TokenObject) and node.name == builder.parser.tokens['NEWLINE']:
continue
else:
stmts.append(node)
@@ -392,7 +392,7 @@
l = len(atoms)
if l == 1 or l==2:
atom0 = atoms[0]
- if isinstance(atom0, TokenObject) and atom0.name == builder.parser.NEWLINE:
+ if isinstance(atom0, TokenObject) and atom0.name == builder.parser.tokens['NEWLINE']:
atom0 = ast.Pass(atom0.lineno)
elif not isinstance(atom0, ast.Stmt):
atom0 = ast.Stmt([atom0], atom0.lineno)
@@ -412,7 +412,7 @@
return
items = []
token = atoms[1]
- if isinstance(token, TokenObject) and token.name == builder.parser.COMMA:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COMMA']:
for i in range(0, l, 2): # this is atoms not 1
items.append(atoms[i])
else:
@@ -452,13 +452,13 @@
atoms = get_atoms(builder, nb)
first_token = atoms[0]
# Case 1 : '(' ...
- if isinstance(first_token, TokenObject) and first_token.name == builder.parser.LPAR:
- if len(atoms) == 2: # and atoms[1].token == builder.parser.RPAR:
+ if isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LPAR']:
+ if len(atoms) == 2: # and atoms[1].token == builder.parser.tokens['RPAR']:
builder.push(ArglistObject([], None, None, first_token.lineno))
elif len(atoms) == 3: # '(' Arglist ')'
# push arglist on the stack
builder.push(atoms[1])
- elif isinstance(first_token, TokenObject) and first_token.name == builder.parser.LSQB:
+ elif isinstance(first_token, TokenObject) and first_token.name == builder.parser.tokens['LSQB']:
if len(atoms) == 3 and isinstance(atoms[1], SlicelistObject):
builder.push(atoms[1])
else:
@@ -516,11 +516,11 @@
atoms = get_atoms(builder, nb)
token = atoms[0]
lineno = token.lineno
- if isinstance(token, TokenObject) and token.name == builder.parser.DOT:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOT']:
# Ellipsis:
builder.push(ast.Ellipsis(lineno))
elif len(atoms) == 1:
- if isinstance(token, TokenObject) and token.name == builder.parser.COLON:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']:
sliceinfos = [None, None, None]
builder.push(SlicelistObject('slice', sliceinfos, lineno))
else:
@@ -530,7 +530,7 @@
sliceinfos = [None, None, None]
infosindex = 0
for token in atoms:
- if isinstance(token, TokenObject) and token.name == builder.parser.COLON:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['COLON']:
infosindex += 1
else:
sliceinfos[infosindex] = token
@@ -578,7 +578,7 @@
# remove '@', '(' and ')' from atoms and use parse_attraccess
for token in atoms[1:]:
if isinstance(token, TokenObject) and \
- token.name in (builder.parser.LPAR, builder.parser.RPAR, builder.parser.NEWLINE):
+ token.name in (builder.parser.tokens['LPAR'], builder.parser.tokens['RPAR'], builder.parser.tokens['NEWLINE']):
# skip those ones
continue
else:
@@ -810,11 +810,11 @@
while index 1:
token = atoms[1]
- if isinstance(token, TokenObject) and token.name == builder.parser.RIGHTSHIFT:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['RIGHTSHIFT']:
dest = atoms[2]
# skip following comma
start = 4
for index in range(start, l, 2):
items.append(atoms[index])
last_token = atoms[-1]
- if isinstance(last_token, TokenObject) and last_token.name == builder.parser.COMMA:
+ if isinstance(last_token, TokenObject) and last_token.name == builder.parser.tokens['COMMA']:
builder.push(ast.Print(items, dest, atoms[0].lineno))
else:
builder.push(ast.Printnl(items, dest, atoms[0].lineno))
@@ -1061,11 +1061,7 @@
class AstBuilder(Wrappable, BaseGrammarBuilder):
"""A builder that directly produce the AST"""
- def __init__(self, parser=None, debug=0, space=None):
- # XXX: parser must become mandatory
- if parser is None:
- from pythonparse import PYTHON_PARSER
- parser = pythonparse.PYTHON_PARSER
+ def __init__(self, parser, debug=0, space=None):
BaseGrammarBuilder.__init__(self, parser, debug)
self.rule_stack = []
self.space = space
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/asthelper.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/asthelper.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/asthelper.py Thu Jan 11 10:34:19 2007
@@ -43,7 +43,7 @@
for index in range(1, l, 2):
token = tokens[index]
assert isinstance(token, TokenObject)
- if token.name != builder.parser.DOT:
+ if token.name != builder.parser.tokens['DOT']:
break
token = tokens[index+1]
assert isinstance(token, TokenObject)
@@ -75,16 +75,16 @@
building_kw = False
kw_built = True
continue
- elif cur_token.name == builder.parser.COMMA:
+ elif cur_token.name == builder.parser.tokens['COMMA']:
index += 1
continue
- elif cur_token.name == builder.parser.EQUAL:
+ elif cur_token.name == builder.parser.tokens['EQUAL']:
index += 1
building_kw = True
continue
- elif cur_token.name == builder.parser.STAR or cur_token.name == builder.parser.DOUBLESTAR:
+ elif cur_token.name == builder.parser.tokens['STAR'] or cur_token.name == builder.parser.tokens['DOUBLESTAR']:
index += 1
- if cur_token.name == builder.parser.STAR:
+ if cur_token.name == builder.parser.tokens['STAR']:
stararg_token = tokens[index]
index += 1
if index >= l:
@@ -119,9 +119,9 @@
token = tokens[index]
index += 1
assert isinstance(token, TokenObject)
- if token.name == builder.parser.LPAR: # nested item
+ if token.name == builder.parser.tokens['LPAR']: # nested item
index, node = parse_fpdef(tokens, index, builder)
- elif token.name == builder.parser.RPAR: # end of current nesting
+ elif token.name == builder.parser.tokens['RPAR']: # end of current nesting
break
else: # name
val = token.get_value()
@@ -131,10 +131,10 @@
token = tokens[index]
index += 1
assert isinstance(token, TokenObject)
- if token.name == builder.parser.COMMA:
+ if token.name == builder.parser.tokens['COMMA']:
comma = True
else:
- assert token.name == builder.parser.RPAR
+ assert token.name == builder.parser.tokens['RPAR']
break
if len(nodes) == 1 and not comma:
node = nodes[0]
@@ -158,19 +158,19 @@
defaults.append(cur_token)
if first_with_default == -1:
first_with_default = len(names) - 1
- elif cur_token.name == builder.parser.COMMA:
+ elif cur_token.name == builder.parser.tokens['COMMA']:
# We could skip test COMMA by incrementing index cleverly
# but we might do some experiment on the grammar at some point
continue
- elif cur_token.name == builder.parser.LPAR:
+ elif cur_token.name == builder.parser.tokens['LPAR']:
index, node = parse_fpdef(tokens, index, builder)
names.append(node)
- elif cur_token.name == builder.parser.STAR or cur_token.name == builder.parser.DOUBLESTAR:
- if cur_token.name == builder.parser.STAR:
+ elif cur_token.name == builder.parser.tokens['STAR'] or cur_token.name == builder.parser.tokens['DOUBLESTAR']:
+ if cur_token.name == builder.parser.tokens['STAR']:
cur_token = tokens[index]
assert isinstance(cur_token, TokenObject)
index += 1
- if cur_token.name == builder.parser.NAME:
+ if cur_token.name == builder.parser.tokens['NAME']:
val = cur_token.get_value()
names.append( ast.AssName( val, consts.OP_ASSIGN ) )
flags |= consts.CO_VARARGS
@@ -185,13 +185,13 @@
raise SyntaxError("incomplete varags", cur_token.lineno,
cur_token.col)
assert isinstance(cur_token, TokenObject)
- if cur_token.name != builder.parser.DOUBLESTAR:
+ if cur_token.name != builder.parser.tokens['DOUBLESTAR']:
raise SyntaxError("Unexpected token", cur_token.lineno,
cur_token.col)
cur_token = tokens[index]
index += 1
assert isinstance(cur_token, TokenObject)
- if cur_token.name == builder.parser.NAME:
+ if cur_token.name == builder.parser.tokens['NAME']:
val = cur_token.get_value()
names.append( ast.AssName( val, consts.OP_ASSIGN ) )
flags |= consts.CO_VARKEYWORDS
@@ -203,7 +203,7 @@
token = tokens[index]
raise SyntaxError("unexpected token" , token.lineno,
token.col)
- elif cur_token.name == builder.parser.NAME:
+ elif cur_token.name == builder.parser.tokens['NAME']:
val = cur_token.get_value()
names.append( ast.AssName( val, consts.OP_ASSIGN ) )
@@ -244,7 +244,7 @@
tok2 = tokens[index]
if not isinstance(tok2, TokenObject):
break
- if tok2.name != builder.parser.COMMA:
+ if tok2.name != builder.parser.tokens['COMMA']:
break
iterables.append(tokens[index+1])
index += 2
@@ -485,7 +485,7 @@
index = 1
while index < len(tokens):
token = tokens[index]
- if isinstance(token, TokenObject) and token.name == builder.parser.DOT:
+ if isinstance(token, TokenObject) and token.name == builder.parser.tokens['DOT']:
index += 1
token = tokens[index]
assert isinstance(token, TokenObject)
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfgrammar.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfgrammar.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfgrammar.py Thu Jan 11 10:34:19 2007
@@ -67,7 +67,7 @@
grammar_grammar()
for _sym, _value in GRAMMAR_GRAMMAR.symbols.items():
- assert not hasattr( GRAMMAR_GRAMMAR, _sym )
+ assert not hasattr( GRAMMAR_GRAMMAR, _sym ), _sym
setattr(GRAMMAR_GRAMMAR, _sym, _value )
for _sym, _value in GRAMMAR_GRAMMAR.tokens.items():
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnflexer.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnflexer.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnflexer.py Thu Jan 11 10:34:19 2007
@@ -136,7 +136,7 @@
end = len(self.input)
pos = self.skip_empty_lines(inp,pos,end)
if pos==end:
- return _p.Token( _p.EOF, None)
+ return _p.build_token( _p.EOF, None)
# at this point nextchar is not a white space nor \n
nextchr = inp[pos]
@@ -148,22 +148,22 @@
self.pos = npos
_endpos = npos - 1
assert _endpos>=0
- return _p.Token( _p.TOK_STRING, inp[pos+1:_endpos])
+ return _p.build_token( _p.TOK_STRING, inp[pos+1:_endpos])
else:
npos = match_symbol( inp, pos, end)
if npos!=pos:
self.pos = npos
if npos!=end and inp[npos]==":":
self.pos += 1
- return _p.Token( _p.TOK_SYMDEF, inp[pos:npos])
+ return _p.build_token( _p.TOK_SYMDEF, inp[pos:npos])
else:
- return _p.Token( _p.TOK_SYMBOL, inp[pos:npos])
+ return _p.build_token( _p.TOK_SYMBOL, inp[pos:npos])
# we still have pos!=end here
chr = inp[pos]
if chr in "[]()*+|":
self.pos = pos+1
- return _p.Token( _p.tok_values[chr], chr)
+ return _p.build_token( _p.tok_values[chr], chr)
self.RaiseError( "Unknown token" )
def peek(self):
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfparse.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfparse.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/ebnfparse.py Thu Jan 11 10:34:19 2007
@@ -1,10 +1,5 @@
-#!/usr/bin/env python
-from grammar import BaseGrammarBuilder, Alternative, Sequence, Token
-from grammar import GrammarProxy, KleeneStar, GrammarElement, build_first_sets
-from grammar import AbstractBuilder, AbstractContext, Parser
-from ebnflexer import GrammarSource
-import ebnfgrammar
-from ebnfgrammar import GRAMMAR_GRAMMAR
+from grammar import Token, GrammarProxy
+from grammar import AbstractBuilder, AbstractContext
ORDA = ord("A")
@@ -32,7 +27,6 @@
return True
-
punct=['>=', '<>', '!=', '<', '>', '<=', '==', '\\*=',
'//=', '%=', '^=', '<<=', '\\*\\*=', '\\', '=',
'\\+=', '>>=', '=', '&=', '/=', '-=', '\n,', '^',
@@ -40,12 +34,10 @@
'%', '<<', '//', '\\', '', '\n\\)', '\\(', ';', ':',
'@', '\\[', '\\]', '`', '\\{', '\\}']
-TERMINALS = [
- 'NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER',
- 'INDENT', 'DEDENT' ]
+TERMINALS = ['NAME', 'NUMBER', 'STRING', 'NEWLINE', 'ENDMARKER',
+ 'INDENT', 'DEDENT' ]
-# FIXME: parsertools.py ? parser/__init__.py ?
class NameToken(Token):
"""A token that is not a keyword"""
def __init__(self, parser, keywords=None):
@@ -142,7 +134,9 @@
"""Remove GrammarProxy objects"""
to_be_deleted = {}
for rule in self.parser.all_rules:
- for i, arg in enumerate(rule.args):
+ # for i, arg in enumerate(rule.args):
+ for i in range(len(rule.args)):
+ arg = rule.args[i]
if isinstance(arg, GrammarProxy):
real_rule = self.parser.root_rules[arg.codename]
if isinstance(real_rule, GrammarProxy):
@@ -161,10 +155,10 @@
"""Returns a new or existing Token"""
if codename in self.tokens:
return self.tokens[codename]
- token = self.tokens[codename] = self.parser.Token(codename)
+ token = self.tokens[codename] = self.parser.build_token(codename)
return token
- def get_symbolcode(self, name ):
+ def get_symbolcode(self, name):
return self.parser.add_symbol( name )
def get_rule( self, name ):
@@ -196,7 +190,7 @@
self.curaltcount += 1
return True
rules = self.pop_rules(self.curseqcount)
- new_rule = self.parser.Sequence( self.new_symbol(), rules )
+ new_rule = self.parser.build_sequence( self.new_symbol(), rules )
self.rule_stack.append( new_rule )
self.curseqcount = 0
self.curaltcount += 1
@@ -205,7 +199,7 @@
self.curaltcount = 0
return True
rules = self.pop_rules(self.curaltcount)
- new_rule = self.parser.Alternative( self.new_symbol(), rules )
+ new_rule = self.parser.build_alternative( self.new_symbol(), rules )
self.rule_stack.append( new_rule )
self.curaltcount = 0
elif _rule == self.gram.group:
@@ -213,7 +207,7 @@
elif _rule == self.gram.option:
# pops the last alternative
rules = self.pop_rules( 1 )
- new_rule = self.parser.KleeneStar( self.new_symbol(), _min=0, _max=1, rule=rules[0] )
+ new_rule = self.parser.build_kleenestar( self.new_symbol(), _min=0, _max=1, rule=rules[0] )
self.rule_stack.append( new_rule )
self.curseqcount += 1
elif _rule == self.gram.rule:
@@ -222,7 +216,7 @@
del self.rule_stack[0]
if isinstance(old_rule,Token):
# Wrap a token into an alternative
- old_rule = self.parser.Alternative( self.current_rule, [old_rule] )
+ old_rule = self.parser.build_alternative( self.current_rule, [old_rule] )
else:
# Make sure we use the codename from the named rule
old_rule.codename = self.current_rule
@@ -243,11 +237,11 @@
self.curseqcount += 1
elif name == self.gram.TOK_STAR:
top = self.rule_stack[-1]
- rule = self.parser.KleeneStar( self.new_symbol(), _min=0, rule=top)
+ rule = self.parser.build_kleenestar( self.new_symbol(), _min=0, rule=top)
self.rule_stack[-1] = rule
elif name == self.gram.TOK_ADD:
top = self.rule_stack[-1]
- rule = self.parser.KleeneStar( self.new_symbol(), _min=1, rule=top)
+ rule = self.parser.build_kleenestar( self.new_symbol(), _min=1, rule=top)
self.rule_stack[-1] = rule
elif name == self.gram.TOK_BAR:
assert self.curseqcount == 0
@@ -276,12 +270,12 @@
if value in self.parser.tok_values:
# punctuation
tokencode = self.parser.tok_values[value]
- tok = self.parser.Token( tokencode, None )
+ tok = self.parser.build_token( tokencode, None )
else:
if not is_py_name(value):
raise RuntimeError("Unknown STRING value ('%s')" % value)
# assume a keyword
- tok = self.parser.Token( self.parser.NAME, value)
+ tok = self.parser.build_token( self.parser.tokens['NAME'], value)
if value not in self.keywords:
self.keywords.append(value)
self.rule_stack.append(tok)
@@ -294,6 +288,8 @@
## txt : the grammar definition
## """
+## from ebnflexer import GrammarSource
+## from ebnfgrammar import GRAMMAR_GRAMMAR
## source = GrammarSource(GRAMMAR_GRAMMAR, txt)
## builder = EBNFBuilder(GRAMMAR_GRAMMAR, dest_parser=parser)
## result = GRAMMAR_GRAMMAR.root_rules['grammar'].match(source, builder)
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/grammar.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/grammar.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/grammar.py Thu Jan 11 10:34:19 2007
@@ -461,7 +461,11 @@
print "Warning: alternative %s has more than one rule " \
"matching Empty" % self
self._reordered = True
- self.args[:] = not_empty_set
+ # self.args[:] = not_empty_set
+ for elt in self.args[:]:
+ self.args.remove(elt)
+ for elt in not_empty_set:
+ self.args.append(elt)
self.args.extend( empty_set )
def validate( self, syntax_node ):
@@ -758,7 +762,7 @@
return "%d" % codename
def add_symbol( self, sym ):
- assert isinstance( sym, str )
+ # assert isinstance( sym, str )
if not sym in self.symbols:
val = self._sym_count
self._sym_count += 1
@@ -768,7 +772,7 @@
return self.symbols[ sym ]
def add_anon_symbol( self, sym ):
- assert isinstance( sym, str )
+ # assert isinstance( sym, str )
if not sym in self.symbols:
val = self._ann_sym_count
self._ann_sym_count -= 1
@@ -778,7 +782,7 @@
return self.symbols[ sym ]
def add_token( self, tok, value = None ):
- assert isinstance( tok, str )
+ # assert isinstance( tok, str )
if not tok in self.tokens:
val = self._sym_count
self._sym_count += 1
@@ -827,48 +831,49 @@
r.reorder_rule()
- def Alternative( self, name_id, args ):
- assert isinstance( name_id, int )
+ def build_alternative( self, name_id, args ):
+ # assert isinstance( name_id, int )
+ assert isinstance(args, list)
alt = Alternative( self, name_id, args )
self.all_rules.append( alt )
return alt
def Alternative_n(self, name, args ):
- assert isinstance(name, str)
+ # assert isinstance(name, str)
name_id = self.add_symbol( name )
- return self.Alternative( name_id, args )
+ return self.build_alternative( name_id, args )
- def Sequence( self, name_id, args ):
- assert isinstance( name_id, int )
+ def build_sequence( self, name_id, args ):
+ # assert isinstance( name_id, int )
alt = Sequence( self, name_id, args )
self.all_rules.append( alt )
return alt
def Sequence_n(self, name, args ):
- assert isinstance(name, str)
+ # assert isinstance(name, str)
name_id = self.add_symbol( name )
- return self.Sequence( name_id, args )
+ return self.build_sequence( name_id, args )
- def KleeneStar( self, name_id, _min = 0, _max = -1, rule = None ):
- assert isinstance( name_id, int )
+ def build_kleenestar( self, name_id, _min = 0, _max = -1, rule = None ):
+ # assert isinstance( name_id, int )
alt = KleeneStar( self, name_id, _min, _max, rule )
self.all_rules.append( alt )
return alt
def KleeneStar_n(self, name, _min = 0, _max = -1, rule = None ):
- assert isinstance(name, str)
+ # assert isinstance(name, str)
name_id = self.add_symbol( name )
- return self.KleeneStar( name_id, _min, _max, rule )
+ return self.build_kleenestar( name_id, _min, _max, rule )
def Token_n(self, name, value = None ):
- assert isinstance( name, str)
- assert value is None or isinstance( value, str)
+ # assert isinstance( name, str)
+ # assert value is None or isinstance( value, str)
name_id = self.add_token( name, value )
- return self.Token( name_id, value )
+ return self.build_token( name_id, value )
- def Token(self, name_id, value = None ):
- assert isinstance( name_id, int )
- assert value is None or isinstance( value, str)
+ def build_token(self, name_id, value = None ):
+ # assert isinstance( name_id, int )
+ # assert value is None or isinstance( value, str)
tok = Token( self, name_id, value )
return tok
Modified: pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonlexer.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonlexer.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/pyparser/pythonlexer.py Thu Jan 11 10:34:19 2007
@@ -121,7 +121,7 @@
endmatch = endDFA.recognize(line)
if endmatch >= 0:
pos = end = endmatch
- tok = parser.Token(parser.STRING, contstr + line[:end])
+ tok = parser.build_token(parser.tokens['STRING'], contstr + line[:end])
token_list.append((tok, line, lnum, pos))
last_comment = ''
# token_list.append((STRING, contstr + line[:end],
@@ -130,7 +130,7 @@
contline = None
elif (needcont and not line.endswith('\\\n') and
not line.endswith('\\\r\n')):
- tok = parser.Token(parser.ERRORTOKEN, contstr + line)
+ tok = parser.build_token(parser.tokens['ERRORTOKEN'], contstr + line)
token_list.append((tok, line, lnum, pos))
last_comment = ''
# token_list.append((ERRORTOKEN, contstr + line,
@@ -156,10 +156,10 @@
if line[pos] in '#\r\n': # skip comments or blank lines
if line[pos] == '#':
- tok = parser.Token(parser.COMMENT, line[pos:])
+ tok = parser.build_token(parser.tokens['COMMENT'], line[pos:])
last_comment = line[pos:]
else:
- tok = parser.Token(parser.NL, line[pos:])
+ tok = parser.build_token(parser.tokens['NL'], line[pos:])
last_comment = ''
# XXX Skip NL and COMMENT Tokens
# token_list.append((tok, line, lnum, pos))
@@ -167,12 +167,12 @@
if column > indents[-1]: # count indents or dedents
indents.append(column)
- tok = parser.Token(parser.INDENT, line[:pos])
+ tok = parser.build_token(parser.tokens['INDENT'], line[:pos])
token_list.append((tok, line, lnum, pos))
last_comment = ''
while column < indents[-1]:
indents = indents[:-1]
- tok = parser.Token(parser.DEDENT, '')
+ tok = parser.build_token(parser.tokens['DEDENT'], '')
token_list.append((tok, line, lnum, pos))
last_comment = ''
else: # continued statement
@@ -199,22 +199,22 @@
token, initial = line[start:end], line[start]
if initial in numchars or \
(initial == '.' and token != '.'): # ordinary number
- tok = parser.Token(parser.NUMBER, token)
+ tok = parser.build_token(parser.tokens['NUMBER'], token)
token_list.append((tok, line, lnum, pos))
last_comment = ''
elif initial in '\r\n':
if parenlev > 0:
- tok = parser.Token(parser.NL, token)
+ tok = parser.build_token(parser.tokens['NL'], token)
last_comment = ''
# XXX Skip NL
else:
- tok = parser.Token(parser.NEWLINE, token)
+ tok = parser.build_token(parser.tokens['NEWLINE'], token)
# XXX YUCK !
tok.value = last_comment
token_list.append((tok, line, lnum, pos))
last_comment = ''
elif initial == '#':
- tok = parser.Token(parser.COMMENT, token)
+ tok = parser.build_token(parser.tokens['COMMENT'], token)
last_comment = token
# XXX Skip # token_list.append((tok, line, lnum, pos))
# token_list.append((COMMENT, token, spos, epos, line))
@@ -224,7 +224,7 @@
if endmatch >= 0: # all on one line
pos = endmatch
token = line[start:pos]
- tok = parser.Token(parser.STRING, token)
+ tok = parser.build_token(parser.tokens['STRING'], token)
token_list.append((tok, line, lnum, pos))
last_comment = ''
else:
@@ -241,11 +241,11 @@
contline = line
break
else: # ordinary string
- tok = parser.Token(parser.STRING, token)
+ tok = parser.build_token(parser.tokens['STRING'], token)
token_list.append((tok, line, lnum, pos))
last_comment = ''
elif initial in namechars: # ordinary name
- tok = parser.Token(parser.NAME, token)
+ tok = parser.build_token(parser.tokens['NAME'], token)
token_list.append((tok, line, lnum, pos))
last_comment = ''
elif initial == '\\': # continued stmt
@@ -261,9 +261,9 @@
(lnum-1, 0), token_list)
if token in parser.tok_values:
punct = parser.tok_values[token]
- tok = parser.Token(punct)
+ tok = parser.build_token(punct)
else:
- tok = parser.Token(parser.OP, token)
+ tok = parser.build_token(parser.tokens['OP'], token)
token_list.append((tok, line, lnum, pos))
last_comment = ''
else:
@@ -273,22 +273,22 @@
if start
Author: adim
Date: Thu Jan 11 10:36:52 2007
New Revision: 36451
Modified:
pypy/branch/ast-experiments/pypy/interpreter/stablecompiler/transformer.py
pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py
pypy/branch/ast-experiments/pypy/module/symbol/__init__.py
Log:
try to avoid using global PYTHON_PARSER
Modified: pypy/branch/ast-experiments/pypy/interpreter/stablecompiler/transformer.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/interpreter/stablecompiler/transformer.py (original)
+++ pypy/branch/ast-experiments/pypy/interpreter/stablecompiler/transformer.py Thu Jan 11 10:36:52 2007
@@ -131,14 +131,14 @@
if hasattr(self, name):
self._dispatch[value] = getattr(self, name)
- self._dispatch[token.NEWLINE] = self.com_NEWLINE
- self._atom_dispatch = {token.LPAR: self.atom_lpar,
- token.LSQB: self.atom_lsqb,
- token.LBRACE: self.atom_lbrace,
- token.BACKQUOTE: self.atom_backquote,
- token.NUMBER: self.atom_number,
- token.STRING: self.atom_string,
- token.NAME: self.atom_name,
+ self._dispatch[stable_parser.tokens['NEWLINE']] = self.com_NEWLINE
+ self._atom_dispatch = {stable_parser.tokens['LPAR']: self.atom_lpar,
+ stable_parser.tokens['LSQB']: self.atom_lsqb,
+ stable_parser.tokens['LBRACE']: self.atom_lbrace,
+ stable_parser.tokens['BACKQUOTE']: self.atom_backquote,
+ stable_parser.tokens['NUMBER']: self.atom_number,
+ stable_parser.tokens['STRING']: self.atom_string,
+ stable_parser.tokens['NAME']: self.atom_name,
}
self.encoding = None
@@ -207,7 +207,7 @@
def single_input(self, node):
# NEWLINE | simple_stmt | compound_stmt NEWLINE
n = node[0][0]
- if n != token.NEWLINE:
+ if n != stable_parser.tokens['NEWLINE']:
stmt = self.com_stmt(node[0])
else:
stmt = Pass()
@@ -217,7 +217,7 @@
doc = self.get_docstring(nodelist, symbol.file_input)
stmts = []
for node in nodelist:
- if node[0] != token.ENDMARKER and node[0] != token.NEWLINE:
+ if node[0] != stable_parser.tokens['ENDMARKER'] and node[0] != stable_parser.tokens['NEWLINE']:
self.com_append_stmt(stmts, node)
if doc is not None:
@@ -238,8 +238,8 @@
item = self.atom_name(nodelist)
i = 1
while i < listlen:
- assert nodelist[i][0] == token.DOT
- assert nodelist[i + 1][0] == token.NAME
+ assert nodelist[i][0] == stable_parser.tokens['DOT']
+ assert nodelist[i + 1][0] == stable_parser.tokens['NAME']
item = Getattr(item, nodelist[i + 1][1])
i += 2
@@ -248,14 +248,14 @@
def decorator(self, nodelist):
# '@' dotted_name [ '(' [arglist] ')' ]
assert len(nodelist) in (3, 5, 6)
- assert nodelist[0][0] == token.AT
- assert nodelist[-1][0] == token.NEWLINE
+ assert nodelist[0][0] == stable_parser.tokens['AT']
+ assert nodelist[-1][0] == stable_parser.tokens['NEWLINE']
assert nodelist[1][0] == symbol.dotted_name
funcname = self.decorator_name(nodelist[1][1:])
if len(nodelist) > 3:
- assert nodelist[2][0] == token.LPAR
+ assert nodelist[2][0] == stable_parser.tokens['LPAR']
expr = self.com_call_function(funcname, nodelist[3])
else:
expr = funcname
@@ -328,7 +328,7 @@
# classdef: 'class' NAME ['(' testlist ')'] ':' suite
name = nodelist[1][1]
doc = self.get_docstring(nodelist[-1])
- if nodelist[2][0] == token.COLON:
+ if nodelist[2][0] == stable_parser.tokens['COLON']:
bases = []
else:
bases = self.com_bases(nodelist[3])
@@ -397,7 +397,7 @@
exprNode = self.lookup_node(en)(en[1:])
if len(nodelist) == 1:
return Discard(exprNode, lineno=exprNode.lineno)
- if nodelist[1][0] == token.EQUAL:
+ if nodelist[1][0] == stable_parser.tokens['EQUAL']:
nodesl = []
for i in range(0, len(nodelist) - 2, 2):
nodesl.append(self.com_assign(nodelist[i], OP_ASSIGN))
@@ -414,9 +414,9 @@
if len(nodelist) == 1:
start = 1
dest = None
- elif nodelist[1][0] == token.RIGHTSHIFT:
+ elif nodelist[1][0] == stable_parser.tokens['RIGHTSHIFT']:
assert len(nodelist) == 3 \
- or nodelist[3][0] == token.COMMA
+ or nodelist[3][0] == stable_parser.tokens['COMMA']
dest = self.com_node(nodelist[2])
start = 4
else:
@@ -424,7 +424,7 @@
start = 1
for i in range(start, len(nodelist), 2):
items.append(self.com_node(nodelist[i]))
- if nodelist[-1][0] == token.COMMA:
+ if nodelist[-1][0] == stable_parser.tokens['COMMA']:
return Print(items, dest, lineno=nodelist[0][2])
return Printnl(items, dest, lineno=nodelist[0][2])
@@ -482,15 +482,15 @@
assert nodelist[1][0] == symbol.dotted_name
assert nodelist[2][1] == 'import'
fromname = self.com_dotted_name(nodelist[1])
- if nodelist[3][0] == token.STAR:
+ if nodelist[3][0] == stable_parser.tokens['STAR']:
return From(fromname, [('*', None)],
lineno=nodelist[0][2])
else:
- if nodelist[3][0] == token.LPAR:
+ if nodelist[3][0] == stable_parser.tokens['LPAR']:
node = nodelist[4]
else:
node = nodelist[3]
- if node[-1][0] == token.COMMA:
+ if node[-1][0] == stable_parser.tokens['COMMA']:
self.syntaxerror("trailing comma not allowed without surrounding parentheses", node)
return From(fromname, self.com_import_as_names(node),
lineno=nodelist[0][2])
@@ -662,7 +662,7 @@
# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
# | 'in' | 'not' 'in' | 'is' | 'is' 'not'
n = nl[1]
- if n[0] == token.NAME:
+ if n[0] == stable_parser.tokens['NAME']:
type = n[1]
if len(nl) == 3:
if type == 'not':
@@ -699,9 +699,9 @@
node = self.com_node(nodelist[0])
for i in range(2, len(nodelist), 2):
right = self.com_node(nodelist[i])
- if nodelist[i-1][0] == token.LEFTSHIFT:
+ if nodelist[i-1][0] == stable_parser.tokens['LEFTSHIFT']:
node = LeftShift([node, right], lineno=nodelist[1][2])
- elif nodelist[i-1][0] == token.RIGHTSHIFT:
+ elif nodelist[i-1][0] == stable_parser.tokens['RIGHTSHIFT']:
node = RightShift([node, right], lineno=nodelist[1][2])
else:
raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
@@ -711,9 +711,9 @@
node = self.com_node(nodelist[0])
for i in range(2, len(nodelist), 2):
right = self.com_node(nodelist[i])
- if nodelist[i-1][0] == token.PLUS:
+ if nodelist[i-1][0] == stable_parser.tokens['PLUS']:
node = Add([node, right], lineno=nodelist[1][2])
- elif nodelist[i-1][0] == token.MINUS:
+ elif nodelist[i-1][0] == stable_parser.tokens['MINUS']:
node = Sub([node, right], lineno=nodelist[1][2])
else:
raise ValueError, "unexpected token: %s" % nodelist[i-1][0]
@@ -724,13 +724,13 @@
for i in range(2, len(nodelist), 2):
right = self.com_node(nodelist[i])
t = nodelist[i-1][0]
- if t == token.STAR:
+ if t == stable_parser.tokens['STAR']:
node = Mul([node, right])
- elif t == token.SLASH:
+ elif t == stable_parser.tokens['SLASH']:
node = Div([node, right])
- elif t == token.PERCENT:
+ elif t == stable_parser.tokens['PERCENT']:
node = Mod([node, right])
- elif t == token.DOUBLESLASH:
+ elif t == stable_parser.tokens['DOUBLESLASH']:
node = FloorDiv([node, right])
else:
raise ValueError, "unexpected token: %s" % t
@@ -742,11 +742,11 @@
t = elt[0]
node = self.lookup_node(nodelist[-1])(nodelist[-1][1:])
# need to handle (unary op)constant here...
- if t == token.PLUS:
+ if t == stable_parser.tokens['PLUS']:
return UnaryAdd(node, lineno=elt[2])
- elif t == token.MINUS:
+ elif t == stable_parser.tokens['MINUS']:
return UnarySub(node, lineno=elt[2])
- elif t == token.TILDE:
+ elif t == stable_parser.tokens['TILDE']:
node = Invert(node, lineno=elt[2])
return node
@@ -755,7 +755,7 @@
node = self.com_node(nodelist[0])
for i in range(1, len(nodelist)):
elt = nodelist[i]
- if elt[0] == token.DOUBLESTAR:
+ if elt[0] == stable_parser.tokens['DOUBLESTAR']:
return Power([node, self.com_node(nodelist[i+1])],
lineno=elt[2])
@@ -769,17 +769,17 @@
return n
def atom_lpar(self, nodelist):
- if nodelist[1][0] == token.RPAR:
+ if nodelist[1][0] == stable_parser.tokens['RPAR']:
return Tuple(())
return self.com_node(nodelist[1])
def atom_lsqb(self, nodelist):
- if nodelist[1][0] == token.RSQB:
+ if nodelist[1][0] == stable_parser.tokens['RSQB']:
return List([], lineno=nodelist[0][2])
return self.com_list_constructor(nodelist[1], nodelist[0][2])
def atom_lbrace(self, nodelist):
- if nodelist[1][0] == token.RBRACE:
+ if nodelist[1][0] == stable_parser.tokens['RBRACE']:
return Dict(())
return self.com_dictmaker(nodelist[1])
@@ -854,10 +854,10 @@
i = 0
while i < len(nodelist):
node = nodelist[i]
- if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
- if node[0] == token.STAR:
+ if node[0] == stable_parser.tokens['STAR'] or node[0] == stable_parser.tokens['DOUBLESTAR']:
+ if node[0] == stable_parser.tokens['STAR']:
node = nodelist[i+1]
- if node[0] == token.NAME:
+ if node[0] == stable_parser.tokens['NAME']:
name = node[1]
if name in names:
self.syntaxerror("duplicate argument '%s' in function definition" %
@@ -869,7 +869,7 @@
if i < len(nodelist):
# should be DOUBLESTAR
t = nodelist[i][0]
- if t == token.DOUBLESTAR:
+ if t == stable_parser.tokens['DOUBLESTAR']:
node = nodelist[i+1]
else:
raise ValueError, "unexpected token: %s" % t
@@ -895,7 +895,7 @@
self.syntaxerror("non-default argument follows default argument",node)
break
- if nodelist[i][0] == token.EQUAL:
+ if nodelist[i][0] == stable_parser.tokens['EQUAL']:
defaults.append(self.com_node(nodelist[i + 1]))
i = i + 2
elif len(defaults):
@@ -909,7 +909,7 @@
def com_fpdef(self, node):
# fpdef: NAME | '(' fplist ')'
- if node[1][0] == token.LPAR:
+ if node[1][0] == stable_parser.tokens['LPAR']:
return self.com_fplist(node[2])
return node[1][1]
@@ -937,7 +937,7 @@
if len(node) == 1:
return dot, None
assert node[1][1] == 'as'
- assert node[2][0] == token.NAME
+ assert node[2][0] == stable_parser.tokens['NAME']
return dot, node[2][1]
def com_dotted_as_names(self, node):
@@ -951,11 +951,11 @@
def com_import_as_name(self, node):
assert node[0] == symbol.import_as_name
node = node[1:]
- assert node[0][0] == token.NAME
+ assert node[0][0] == stable_parser.tokens['NAME']
if len(node) == 1:
return node[0][1], None
assert node[1][1] == 'as', node
- assert node[2][0] == token.NAME
+ assert node[2][0] == stable_parser.tokens['NAME']
return node[0][1], node[2][1]
def com_import_as_names(self, node):
@@ -998,7 +998,7 @@
expr1 = expr2 = None
clauses.append((expr1, expr2, self.com_node(nodelist[i+2])))
- if node[0] == token.NAME:
+ if node[0] == stable_parser.tokens['NAME']:
elseNode = self.com_node(nodelist[i+2])
return TryExcept(self.com_node(nodelist[2]), clauses, elseNode,
lineno=nodelist[0][2])
@@ -1042,7 +1042,7 @@
primary = self.com_node(node[1])
for i in range(2, len(node)-1):
ch = node[i]
- if ch[0] == token.DOUBLESTAR:
+ if ch[0] == stable_parser.tokens['DOUBLESTAR']:
self.syntaxerror( "can't assign to operator", node)
primary = self.com_apply_trailer(primary, ch)
return self.com_assign_trailer(primary, node[-1],
@@ -1050,16 +1050,16 @@
node = node[1]
elif t == symbol.atom:
t = node[1][0]
- if t == token.LPAR:
+ if t == stable_parser.tokens['LPAR']:
node = node[2]
- if node[0] == token.RPAR:
+ if node[0] == stable_parser.tokens['RPAR']:
self.syntaxerror( "can't assign to ()", node)
- elif t == token.LSQB:
+ elif t == stable_parser.tokens['LSQB']:
node = node[2]
- if node[0] == token.RSQB:
+ if node[0] == stable_parser.tokens['RSQB']:
self.syntaxerror( "can't assign to []", node)
return self.com_assign_list(node, assigning)
- elif t == token.NAME:
+ elif t == stable_parser.tokens['NAME']:
if node[1][1] == "__debug__":
self.syntaxerror( "can not assign to __debug__", node )
if node[1][1] == "None":
@@ -1085,7 +1085,7 @@
if i + 1 < len(node):
if node[i + 1][0] == symbol.list_for:
self.syntaxerror( "can't assign to list comprehension", node)
- assert node[i + 1][0] == token.COMMA, node[i + 1]
+ assert node[i + 1][0] == stable_parser.tokens['COMMA'], node[i + 1]
assigns.append(self.com_assign(node[i], assigning))
return AssList(assigns, lineno=extractLineNo(node))
@@ -1094,11 +1094,11 @@
def com_assign_trailer(self, primary, node, assigning):
t = node[1][0]
- if t == token.DOT:
+ if t == stable_parser.tokens['DOT']:
return self.com_assign_attr(primary, node[2], assigning)
- if t == token.LSQB:
+ if t == stable_parser.tokens['LSQB']:
return self.com_subscriptlist(primary, node[2], assigning)
- if t == token.LPAR:
+ if t == stable_parser.tokens['LPAR']:
if assigning==OP_DELETE:
self.syntaxerror( "can't delete function call", node)
else:
@@ -1146,7 +1146,7 @@
assert len(nodelist[i:]) == 1
return self.com_list_comprehension(values[0],
nodelist[i])
- elif nodelist[i][0] == token.COMMA:
+ elif nodelist[i][0] == stable_parser.tokens['COMMA']:
continue
values.append(self.com_node(nodelist[i]))
return List(values, lineno=lineno)
@@ -1245,29 +1245,29 @@
def com_apply_trailer(self, primaryNode, nodelist):
t = nodelist[1][0]
- if t == token.LPAR:
+ if t == stable_parser.tokens['LPAR']:
return self.com_call_function(primaryNode, nodelist[2])
- if t == token.DOT:
+ if t == stable_parser.tokens['DOT']:
return self.com_select_member(primaryNode, nodelist[2])
- if t == token.LSQB:
+ if t == stable_parser.tokens['LSQB']:
return self.com_subscriptlist(primaryNode, nodelist[2], OP_APPLY)
self.syntaxerror( 'unknown node type: %s' % t, nodelist[1])
def com_select_member(self, primaryNode, nodelist):
- if nodelist[0] != token.NAME:
+ if nodelist[0] != stable_parser.tokens['NAME']:
self.syntaxerror( "member must be a name", nodelist[0])
return Getattr(primaryNode, nodelist[1], lineno=nodelist[2])
def com_call_function(self, primaryNode, nodelist):
- if nodelist[0] == token.RPAR:
+ if nodelist[0] == stable_parser.tokens['RPAR']:
return CallFunc(primaryNode, [], lineno=extractLineNo(nodelist))
args = []
kw = 0
len_nodelist = len(nodelist)
for i in range(1, len_nodelist, 2):
node = nodelist[i]
- if node[0] == token.STAR or node[0] == token.DOUBLESTAR:
+ if node[0] == stable_parser.tokens['STAR'] or node[0] == stable_parser.tokens['DOUBLESTAR']:
break
kw, result = self.com_argument(node, kw)
@@ -1281,7 +1281,7 @@
else:
# No broken by star arg, so skip the last one we processed.
i = i + 1
- if i < len_nodelist and nodelist[i][0] == token.COMMA:
+ if i < len_nodelist and nodelist[i][0] == stable_parser.tokens['COMMA']:
# need to accept an application that looks like "f(a, b,)"
i = i + 1
star_node = dstar_node = None
@@ -1289,11 +1289,11 @@
tok = nodelist[i]
ch = nodelist[i+1]
i = i + 3
- if tok[0]==token.STAR:
+ if tok[0]==stable_parser.tokens['STAR']:
if star_node is not None:
self.syntaxerror( 'already have the varargs indentifier', tok )
star_node = self.com_node(ch)
- elif tok[0]==token.DOUBLESTAR:
+ elif tok[0]==stable_parser.tokens['DOUBLESTAR']:
if dstar_node is not None:
self.syntaxerror( 'already have the kwargs indentifier', tok )
dstar_node = self.com_node(ch)
@@ -1312,9 +1312,9 @@
return 0, self.com_node(nodelist[1])
result = self.com_node(nodelist[3])
n = nodelist[1]
- while len(n) == 2 and n[0] != token.NAME:
+ while len(n) == 2 and n[0] != stable_parser.tokens['NAME']:
n = n[1]
- if n[0] != token.NAME:
+ if n[0] != stable_parser.tokens['NAME']:
self.syntaxerror( "keyword can't be an expression (%s)"%n[0], n)
node = Keyword(n[1], result, lineno=n[2])
return 1, node
@@ -1328,8 +1328,8 @@
# backwards compat slice for '[i:j]'
if len(nodelist) == 2:
sub = nodelist[1]
- if (sub[1][0] == token.COLON or \
- (len(sub) > 2 and sub[2][0] == token.COLON)) and \
+ if (sub[1][0] == stable_parser.tokens['COLON'] or \
+ (len(sub) > 2 and sub[2][0] == stable_parser.tokens['COLON'])) and \
sub[-1][0] != symbol.sliceop:
return self.com_slice(primary, sub, assigning)
@@ -1343,9 +1343,9 @@
# slice_item: expression | proper_slice | ellipsis
ch = node[1]
t = ch[0]
- if t == token.DOT and node[2][0] == token.DOT:
+ if t == stable_parser.tokens['DOT'] and node[2][0] == stable_parser.tokens['DOT']:
return Ellipsis()
- if t == token.COLON or len(node) > 2:
+ if t == stable_parser.tokens['COLON'] or len(node) > 2:
return self.com_sliceobj(node)
return self.com_node(ch)
@@ -1361,7 +1361,7 @@
items = []
- if node[1][0] == token.COLON:
+ if node[1][0] == stable_parser.tokens['COLON']:
items.append(Const(None))
i = 2
else:
@@ -1389,7 +1389,7 @@
# short_slice: [lower_bound] ":" [upper_bound]
lower = upper = None
if len(node) == 3:
- if node[1][0] == token.COLON:
+ if node[1][0] == stable_parser.tokens['COLON']:
upper = self.com_node(node[2])
else:
lower = self.com_node(node[1])
@@ -1416,7 +1416,7 @@
return self.get_docstring(sub)
return None
if n == symbol.atom:
- if node[0][0] == token.STRING:
+ if node[0][0] == stable_parser.tokens['STRING']:
s = ''
for t in node:
s = s + eval(t[1])
@@ -1453,13 +1453,13 @@
# comp_op: '<' | '>' | '=' | '>=' | '<=' | '<>' | '!=' | '=='
# | 'in' | 'not' 'in' | 'is' | 'is' 'not'
_cmp_types = {
- token.LESS : '<',
- token.GREATER : '>',
- token.EQEQUAL : '==',
- token.EQUAL : '==',
- token.LESSEQUAL : '<=',
- token.GREATEREQUAL : '>=',
- token.NOTEQUAL : '!=',
+ stable_parser.tokens['LESS'] : '<',
+ stable_parser.tokens['GREATER'] : '>',
+ stable_parser.tokens['EQEQUAL'] : '==',
+ stable_parser.tokens['EQUAL'] : '==',
+ stable_parser.tokens['LESSEQUAL'] : '<=',
+ stable_parser.tokens['GREATEREQUAL'] : '>=',
+ stable_parser.tokens['NOTEQUAL'] : '!=',
}
_assign_types = [
@@ -1478,20 +1478,20 @@
symbol.factor,
]
-import types
-_names = {}
-for k, v in sym_name.items():
- _names[k] = v
-for k, v in token.tok_name.items():
- _names[k] = v
-
-def debug_tree(tree):
- l = []
- for elt in tree:
- if type(elt) == types.IntType:
- l.append(_names.get(elt, elt))
- elif type(elt) == types.StringType:
- l.append(elt)
- else:
- l.append(debug_tree(elt))
- return l
+# import types
+# _names = {}
+# for k, v in sym_name.items():
+# _names[k] = v
+# for k, v in token.tok_name.items():
+# _names[k] = v
+#
+# def debug_tree(tree):
+# l = []
+# for elt in tree:
+# if type(elt) == types.IntType:
+# l.append(_names.get(elt, elt))
+# elif type(elt) == types.StringType:
+# l.append(elt)
+# else:
+# l.append(debug_tree(elt))
+# return l
Modified: pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py (original)
+++ pypy/branch/ast-experiments/pypy/module/recparser/pyparser.py Thu Jan 11 10:36:52 2007
@@ -8,11 +8,13 @@
from pypy.interpreter.typedef import interp_attrproperty, GetSetProperty
from pypy.interpreter.pycode import PyCode
from pypy.interpreter.pyparser.syntaxtree import TokenNode, SyntaxNode, AbstractSyntaxVisitor
-from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER
+from pypy.interpreter.pyparser.pythonparse import make_pyparser
from pypy.interpreter.pyparser.error import SyntaxError
from pypy.interpreter.pyparser import grammar, symbol, pytoken
from pypy.interpreter.argument import Arguments
+# backward compat (temp)
+PYTHON_PARSER = make_pyparser()
__all__ = [ "ASTType", "STType", "suite", "expr" ]
@@ -43,14 +45,15 @@
def visit_tokennode( self, node ):
space = self.space
+ tokens = space.parser.tokens
num = node.name
lineno = node.lineno
if node.value is not None:
val = node.value
else:
- if num not in ( pytoken.NEWLINE, pytoken.INDENT,
- pytoken.DEDENT, pytoken.ENDMARKER ):
- val = pytoken.tok_rpunct[num]
+ if num not in ( tokens['NEWLINE'], tokens['INDENT'],
+ tokens['DEDENT'], tokens['ENDMARKER'] ):
+ val = space.parser.tok_values[num]
else:
val = node.value or ''
if self.line_info:
@@ -180,7 +183,7 @@
items = space.unpackiterable( w_sequence )
nodetype = space.int_w( items[0] )
is_syntax = True
- if nodetype>=0 and nodetype=0 and nodetype < pytoken.N_TOKENS:
is_syntax = False
if is_syntax:
nodes = []
@@ -202,7 +205,7 @@
def source2ast(space, source):
from pypy.interpreter.pyparser.pythonutil import AstBuilder, PYTHON_PARSER
- builder = AstBuilder(space=space)
+ builder = AstBuilder(parser=PYTHON_PARSER, space=space)
PYTHON_PARSER.parse_source(source, 'file_input', builder)
ast_tree = builder.rule_stack[-1]
return space.wrap(ast_tree)
Modified: pypy/branch/ast-experiments/pypy/module/symbol/__init__.py
==============================================================================
--- pypy/branch/ast-experiments/pypy/module/symbol/__init__.py (original)
+++ pypy/branch/ast-experiments/pypy/module/symbol/__init__.py Thu Jan 11 10:36:52 2007
@@ -20,10 +20,11 @@
# Export the values from our custom symbol module.
# Skip negative values (the corresponding symbols are not visible in
# pure Python).
-from pypy.interpreter.pyparser.pythonparse import PYTHON_PARSER
+from pypy.interpreter.pyparser.pythonparse import make_pyparser
+parser = make_pyparser()
sym_name = {}
-for name, val in PYTHON_PARSER.symbols.items():
+for name, val in parser.symbols.items():
if val >= 0:
Module.interpleveldefs[name] = 'space.wrap(%d)' % val
sym_name[val] = name
From cfbolz at codespeak.net Thu Jan 11 10:46:49 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu, 11 Jan 2007 10:46:49 +0100 (CET)
Subject: [pypy-svn] r36452 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070111094649.A07D01007C@code0.codespeak.net>
Author: cfbolz
Date: Thu Jan 11 10:46:47 2007
New Revision: 36452
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
Log:
(all): planning for today
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt Thu Jan 11 10:46:47 2007
@@ -16,11 +16,11 @@
* Alexandre
* Sylvain
* Niko
+ * Eric
later
-----
- * Eric
Tasks
@@ -31,26 +31,29 @@
* "virtual frames" (Samuele, Arre): funfunfun. basic test is working,
manually written virtualizable structs can be change within the jit-generated
- code and the changes are seen from outside. IN-PROGRESS
+ code and the changes are seen from outside.
+ started a new test, refactoring necessary. IN-PROGRESS
- write a small interpreter that shows the performance problems without having
to use the full pypy
- actually implement support for this in the rtyper and the jit...
-* have register allocation (Michael, half Armin): IN-PROGRESS: redesigned the
- backend interface a bit, adapted the llgraph and i386 backends to the
- changes. now: fixing llvm and ppc backends
+* have register allocation: IN-PROGRESS: redesigned the
+ backend interface a bit, adapted all the backends to the changes. Michael
+ started completing the PPC backend, but is getting annoyed
+ Armin started working on register allocation on i386
+
py.test and the py-lib
----------------------
* polish the code and documentation of the py lib, and eventually
- release it IN-PROGRESS (Holger, Maciek)
+ release it MORE PROGRESS
* integrate api-doc and source-viewer on the py-lib web-page IN-PROGRESS
- (Guido, Maciek around)
+ (Guido, Holger)
* use source-viewer on more code? pypy? IN-PROGRESS
@@ -58,6 +61,8 @@
* (provide code search facility)
+* detailed (and growing) TODO list in py/documentation/TODO.txt
+
interpreter prototypes
----------------------
@@ -74,7 +79,7 @@
Integration and Configuration
-----------------------------
-* actually use the build tool during the sprint (Guido, Carl Friedrich): DONE
+* actually use the build tool during the sprint (Michael, Carl Friedrich): DONE
WITH BUGS
* think about py-lib and pypy debian packaging
@@ -88,15 +93,23 @@
Other
-----
-* progress on the JavaScript interpreter (Leonardo, half Armin): IN-PROGRESS,
- the JS intepreter translates
+* progress on the JavaScript interpreter (Leonardo, Maciek): IN-PROGRESS,
+ the JS intepreter translates. There is now an interactive interpreter.
-* Java backend
+* Java backend (Niko, Antonio): lot of random problems fixed, test_class runs
+ completely. test_pbc is next!
+
+* investigate why the annotator fails when doing --faassen with gencli?!
+ (Anto, general wizards around)
* discuss refinement interface for external functions
* (make py-lib run on pypy-c) PROGRESS: the compiler problems are fixed
+* "shadow tracking" (Carl Friedrich, Samuele), DONE
+
+* progress on the LLVM JIT code generator (Eric, Armin)
+
Discussions during the sprint
=============================
@@ -110,4 +123,5 @@
* release plannings: saturday 5pm
-* pypy and py-lib debian packaging discussion: thursday morning 10am
+* pypy and py-lib debian packaging discussion: thursday morning 11am
+ (Michael, Alexandre, Carl Friedrich, Sylvain)
From afayolle at codespeak.net Thu Jan 11 10:49:06 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Thu, 11 Jan 2007 10:49:06 +0100 (CET)
Subject: [pypy-svn] r36453 - pypy/dist/pypy/translator/lisp
Message-ID: <20070111094906.E3DAD10080@code0.codespeak.net>
Author: afayolle
Date: Thu Jan 11 10:49:06 2007
New Revision: 36453
Modified:
pypy/dist/pypy/translator/lisp/buildcl.py
Log:
fix sysfind usage to new semantics
Modified: pypy/dist/pypy/translator/lisp/buildcl.py
==============================================================================
--- pypy/dist/pypy/translator/lisp/buildcl.py (original)
+++ pypy/dist/pypy/translator/lisp/buildcl.py Thu Jan 11 10:49:06 2007
@@ -11,9 +11,7 @@
global_cl = None
def is_on_path(name):
- try:
- py.path.local.sysfind(name)
- except py.error.ENOENT:
+ if py.path.local.sysfind(name) is None:
return False
else:
return True
From ericvrp at codespeak.net Thu Jan 11 11:02:13 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Thu, 11 Jan 2007 11:02:13 +0100 (CET)
Subject: [pypy-svn] r36454 - pypy/dist/pypy/translator/llvm
Message-ID: <20070111100213.F332810080@code0.codespeak.net>
Author: ericvrp
Date: Thu Jan 11 11:01:59 2007
New Revision: 36454
Modified:
pypy/dist/pypy/translator/llvm/externs2ll.py
Log:
small fix to be more llvm-gcc4 compatible
Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py (original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py Thu Jan 11 11:01:59 2007
@@ -105,6 +105,8 @@
line = "declare %s %s" % (cconv, line[len(declaretag):])
ll_lines2.append(line)
+ ll_lines2.append("declare ccc void %abort()")
+
llcode = '\n'.join(ll_lines2)
try:
decl, impl = llcode.split('implementation')
From arigo at codespeak.net Thu Jan 11 11:08:19 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 11 Jan 2007 11:08:19 +0100 (CET)
Subject: [pypy-svn] r36455 - pypy/dist/pypy/doc
Message-ID: <20070111100819.C970510080@code0.codespeak.net>
Author: arigo
Date: Thu Jan 11 11:08:03 2007
New Revision: 36455
Modified:
pypy/dist/pypy/doc/_ref.txt
pypy/dist/pypy/doc/index.txt
pypy/dist/pypy/doc/translation.txt
Log:
Missing translator/cl -> translator/lisp renamings.
Modified: pypy/dist/pypy/doc/_ref.txt
==============================================================================
--- pypy/dist/pypy/doc/_ref.txt (original)
+++ pypy/dist/pypy/doc/_ref.txt Thu Jan 11 11:08:03 2007
@@ -103,12 +103,12 @@
.. _`pypy/translator/c/src/`: ../../pypy/translator/c/src
.. _`pypy/translator/c/src/ll_os.h`: ../../pypy/translator/c/src/ll_os.h
.. _`pypy/translator/c/test/test_extfunc.py`: ../../pypy/translator/c/test/test_extfunc.py
-.. _`translator/cl/`: ../../pypy/translator/cl
.. _`translator/cli/`: ../../pypy/translator/cli
.. _`translator/goal/`: ../../pypy/translator/goal
.. _`pypy/translator/goal/targetnopstandalone.py`: ../../pypy/translator/goal/targetnopstandalone.py
.. _`translator/js/`: ../../pypy/translator/js
.. _`translator/jvm/`: ../../pypy/translator/jvm
+.. _`translator/lisp/`: ../../pypy/translator/lisp
.. _`translator/llvm/`: ../../pypy/translator/llvm
.. _`translator/squeak/`: ../../pypy/translator/squeak
.. _`translator/stackless/`: ../../pypy/translator/stackless
Modified: pypy/dist/pypy/doc/index.txt
==============================================================================
--- pypy/dist/pypy/doc/index.txt (original)
+++ pypy/dist/pypy/doc/index.txt Thu Jan 11 11:08:03 2007
@@ -263,7 +263,7 @@
`translator/c/`_ the `GenC backend`_, producing C code from an
RPython program (generally via the RTyper)
-`translator/cl/`_ the `Common Lisp backend`_ (incomplete)
+`translator/lisp/`_ the `Common Lisp backend`_ (incomplete)
`translator/cli/`_ the `CLI backend`_ for `.NET`_ (Microsoft CLR or Mono_)
Modified: pypy/dist/pypy/doc/translation.txt
==============================================================================
--- pypy/dist/pypy/doc/translation.txt (original)
+++ pypy/dist/pypy/doc/translation.txt Thu Jan 11 11:08:03 2007
@@ -95,7 +95,7 @@
.. _`play around`: getting-started.html#trying-out-the-translator
.. _`Flow Object Space`: objspace.html#the-flow-object-space
.. _`control flow graph`: objspace.html#the-flow-model
-.. _`Common Lisp`: http://codespeak.net/pypy/dist/pypy/translator/cl/
+.. _`Common Lisp`: http://codespeak.net/pypy/dist/pypy/translator/lisp/
.. _Pyrex: http://codespeak.net/pypy/dist/pypy/translator/pyrex/
.. _JavaScript: http://codespeak.net/pypy/dist/pypy/translator/js/
.. _Squeak: http://codespeak.net/pypy/dist/pypy/translator/squeak/
From ericvrp at codespeak.net Thu Jan 11 11:26:03 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Thu, 11 Jan 2007 11:26:03 +0100 (CET)
Subject: [pypy-svn] r36457 - pypy/dist/pypy/translator/llvm/test
Message-ID: <20070111102603.D11F510080@code0.codespeak.net>
Author: ericvrp
Date: Thu Jan 11 11:26:02 2007
New Revision: 36457
Modified:
pypy/dist/pypy/translator/llvm/test/runtest.py
Log:
skip translator/llvm tests when llvm version >= 2.0
Modified: pypy/dist/pypy/translator/llvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/runtest.py (original)
+++ pypy/dist/pypy/translator/llvm/test/runtest.py Thu Jan 11 11:26:02 2007
@@ -4,6 +4,7 @@
from pypy.translator.llvm.buildllvm import llvm_is_on_path, llvm_version
optimize_tests = False
MINIMUM_LLVM_VERSION = 1.7
+MAXIMUM_LLVM_VERSION = 2.0
ext_modules = []
@@ -37,6 +38,10 @@
py.test.skip("llvm version not up-to-date (found "
"%.1f, should be >= %.1f)" % (v, MINIMUM_LLVM_VERSION))
return False
+ elif v >= MAXIMUM_LLVM_VERSION:
+ py.test.skip("llvm version %.1f and higher are not yet supported (found %.1f)" % (
+ MAXIMUM_LLVM_VERSION, v))
+ return False
return True
def compile_test(function, annotation, isolate=True, **kwds):
From arigo at codespeak.net Thu Jan 11 11:40:32 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 11 Jan 2007 11:40:32 +0100 (CET)
Subject: [pypy-svn] r36460 - in pypy/dist/pypy: module/posix rpython
rpython/module translator/c translator/c/src translator/c/test
Message-ID: <20070111104032.EA3E410091@code0.codespeak.net>
Author: arigo
Date: Thu Jan 11 11:40:26 2007
New Revision: 36460
Modified:
pypy/dist/pypy/module/posix/__init__.py
pypy/dist/pypy/module/posix/interp_posix.py
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/translator/c/extfunc.py
pypy/dist/pypy/translator/c/src/ll_os.h
pypy/dist/pypy/translator/c/test/test_extfunc.py
Log:
Add os.umask support, to make test_file pass again, as the posix module
is now always enabled (test_file used to run on top of the faked posix
with py.py).
Modified: pypy/dist/pypy/module/posix/__init__.py
==============================================================================
--- pypy/dist/pypy/module/posix/__init__.py (original)
+++ pypy/dist/pypy/module/posix/__init__.py Thu Jan 11 11:40:26 2007
@@ -47,6 +47,7 @@
'pipe' : 'interp_posix.pipe',
'chmod' : 'interp_posix.chmod',
'rename' : 'interp_posix.rename',
+ 'umask' : 'interp_posix.umask',
'_exit' : 'interp_posix._exit',
#'getuid' : 'interp_posix.getuid',
#'geteuid' : 'interp_posix.geteuid',
Modified: pypy/dist/pypy/module/posix/interp_posix.py
==============================================================================
--- pypy/dist/pypy/module/posix/interp_posix.py (original)
+++ pypy/dist/pypy/module/posix/interp_posix.py Thu Jan 11 11:40:26 2007
@@ -348,6 +348,12 @@
raise wrap_oserror(space, e)
rename.unwrap_spec = [ObjSpace, str, str]
+def umask(space, mask):
+ "Set the current numeric umask and return the previous umask."
+ prevmask = os.umask(mask)
+ return space.wrap(prevmask)
+umask.unwrap_spec = [ObjSpace, int]
+
def getpid(space):
"Return the current process id."
try:
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Thu Jan 11 11:40:26 2007
@@ -217,6 +217,7 @@
declare(os.pipe , pipeannotation, 'll_os/pipe')
declare(os.chmod , noneannotation, 'll_os/chmod')
declare(os.rename , noneannotation, 'll_os/rename')
+declare(os.umask , int , 'll_os/umask')
declare(os._exit , noneannotation, 'll_os/_exit')
if hasattr(os, 'kill'):
declare(os.kill , noneannotation, 'll_os/kill')
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Thu Jan 11 11:40:26 2007
@@ -152,6 +152,10 @@
os.rename(cls.from_rstr(path1), cls.from_rstr(path2))
ll_os_rename.suggested_primitive = True
+ def ll_os_umask(cls, mask):
+ return os.umask(mask)
+ ll_os_umask.suggested_primitive = True
+
def ll_os_getpid(cls):
return os.getpid()
ll_os_getpid.suggested_primitive = True
Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/dist/pypy/translator/c/extfunc.py Thu Jan 11 11:40:26 2007
@@ -54,6 +54,7 @@
impl.ll_os_pipe.im_func: 'LL_os_pipe',
impl.ll_os_chmod.im_func: 'LL_os_chmod',
impl.ll_os_rename.im_func: 'LL_os_rename',
+ impl.ll_os_umask.im_func: 'LL_os_umask',
impl.ll_os_getpid.im_func: 'LL_os_getpid',
impl.ll_os_kill.im_func: 'LL_os_kill',
impl.ll_os_link.im_func: 'LL_os_link',
Modified: pypy/dist/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h (original)
+++ pypy/dist/pypy/translator/c/src/ll_os.h Thu Jan 11 11:40:26 2007
@@ -74,6 +74,7 @@
void LL_os_rmdir(RPyString * path);
void LL_os_chmod(RPyString * path, int mode);
void LL_os_rename(RPyString * path1, RPyString * path2);
+int LL_os_umask(int mode);
long LL_os_getpid(void);
void LL_os_kill(int pid, int sig);
void LL_os_link(RPyString * path1, RPyString * path2);
@@ -350,6 +351,10 @@
}
}
+int LL_os_umask(int mode) {
+ return umask(mode);
+}
+
long LL_os_getpid(void) {
return getpid();
}
Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_extfunc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_extfunc.py Thu Jan 11 11:40:26 2007
@@ -533,6 +533,15 @@
assert os.path.exists(tmpfile2)
assert not os.path.exists(tmpfile1)
+def test_os_umask():
+ def does_stuff():
+ mask1 = os.umask(0660)
+ mask2 = os.umask(mask1)
+ return mask2
+ f1 = compile(does_stuff, [])
+ res = f1()
+ assert res == 0660
+
if hasattr(os, 'getpid'):
def test_os_getpid():
def does_stuff():
From cfbolz at codespeak.net Thu Jan 11 11:51:05 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu, 11 Jan 2007 11:51:05 +0100 (CET)
Subject: [pypy-svn] r36462 - pypy/extradoc/minute
Message-ID: <20070111105105.11E1E10093@code0.codespeak.net>
Author: cfbolz
Date: Thu Jan 11 11:51:04 2007
New Revision: 36462
Added:
pypy/extradoc/minute/packaging-meeting-2007-01-11.txt
Log:
minutes of the debian packaging discussion
Added: pypy/extradoc/minute/packaging-meeting-2007-01-11.txt
==============================================================================
--- (empty file)
+++ pypy/extradoc/minute/packaging-meeting-2007-01-11.txt Thu Jan 11 11:51:04 2007
@@ -0,0 +1,85 @@
+========================================
+PyPy and Py-lib Debian packaging meeting
+========================================
+
+Attendees:
+ - Alexandre
+ - Sylvain
+ - Michael
+ - Carl Friedrich (minutes)
+
+The Py-lib
+==========
+
+Basic package is working, some patches necessary.
+
+ * greenlets only on platforms where they are supported
+
+Open issue:
+
+ * should the unittests be in the package?
+ yes, since it does not cost much and is actually easier than removing them
+
+
+
+PyPy
+====
+
+packages:
+
+ * pypy-dev
+ * pypy-lib
+ * pypy-docs
+ * binary packages (pypy-stackless, pypy-logic, pypy-jit) using the C backend
+
+Goals:
+
+ * get dependencies right
+ * pypy-dev:
+ * run py.py
+ * pypy-translate.py
+ * what to do with the targets?
+ * pypy-jscompile.py
+ * would be nice
+
+Dependencies:
+
+ * required (things to run py.py)
+ * Python
+ * py-lib
+
+ * recommended (for translate.py)
+ * pypy-doc
+ * pygame
+ * python-dev
+ * gcc
+ * mono
+ * boehm
+ * graphviz
+ * python-ctypes
+ * spidermonkey
+ * common lisp (which one?)
+ * jasmin (in suggested?)
+ * llvm?
+ * libbz2-dev
+ * ctypes
+
+
+Solved problems:
+
+ * pypy/_cache is symlinked to /var/pypy_cache (or whatever)
+
+
+still to do:
+
+ * rewrite getting started to work with debian
+
+
+Issues to fix in PyPy:
+
+ * maybe remove the logic object space target?
+
+ * what do to with geninterp (in general)
+
+ * be able to specify an executable name for translate.py
+
From mwh at codespeak.net Thu Jan 11 12:13:16 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Thu, 11 Jan 2007 12:13:16 +0100 (CET)
Subject: [pypy-svn] r36463 - pypy/dist/pypy/bin
Message-ID: <20070111111316.89A8B10080@code0.codespeak.net>
Author: mwh
Date: Thu Jan 11 12:13:08 2007
New Revision: 36463
Modified:
pypy/dist/pypy/bin/startcompile.py
Log:
(mwh, cfbolz)
configs already have a nice __repr__, let's use that.
Modified: pypy/dist/pypy/bin/startcompile.py
==============================================================================
--- pypy/dist/pypy/bin/startcompile.py (original)
+++ pypy/dist/pypy/bin/startcompile.py Thu Jan 11 12:13:08 2007
@@ -27,7 +27,7 @@
initcode = """
import sys
sys.path += %r
-
+
try:
from pypy.tool.build import metaserver_instance
from pypy.tool.build import build
@@ -57,7 +57,7 @@
sysinfo = make_dict(config.system_config)
compileinfo = make_dict(config.compile_config)
-
+
buildrequest = build.BuildRequest(args[0], sysinfo, compileinfo,
config.svnpath_to_url(
tool_config.svnpath),
@@ -68,9 +68,7 @@
for k, v in sysinfo.items():
print '%s: %r' % (k, v)
print
- for k, v in compileinfo.items():
- print '%s: %r' % (k, v)
- print
+ print config.compile_config
if config.server in ['localhost', '127.0.0.1']:
gw = PopenGateway()
From santagada at codespeak.net Thu Jan 11 12:31:20 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 12:31:20 +0100 (CET)
Subject: [pypy-svn] r36464 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070111113120.288FA10080@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 12:31:17 2007
New Revision: 36464
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/jsparser.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
for and eval working
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Thu Jan 11 12:31:17 2007
@@ -61,6 +61,9 @@
temp_tree = parse_bytecode(bytecode)
return from_tree(temp_tree)
+def evaljs(ctx, code):
+ return load_source(code.ToString()).execute(ctx)
+
class Interpreter(object):
"""Creates a js interpreter"""
def __init__(self):
@@ -70,6 +73,7 @@
self.w_Global.Put('prototype', W_String('Object'))
self.w_Global.Put('Object', self.w_Object)
self.global_context = global_context(self.w_Global)
+ self.w_Global.Put('eval', W_Builtin(evaljs, context=True, args=1))
def run(self, script):
"""run the interpreter"""
@@ -288,6 +292,17 @@
name = op1.ToString()
return W_Boolean(op2.HasProperty(name))
+class Increment(Expression):
+ def __init__(self, op):
+ self.op = op
+
+ def eval(self, ctx):
+ thing = self.op.eval(ctx)
+ val = thing.GetValue()
+ x = val.ToNumber()
+ resl = Plus(W_Number(x), W_Number(1)).eval(ctx).GetValue()
+ thing.PutValue(resl)
+ return resl
class Index(Expression):
def __init__(self, left, expr):
@@ -477,6 +492,19 @@
while self.condition.eval(ctx).ToBoolean():
self.body.execute(ctx)
+class For(Statement):
+ def __init__(self, setup, condition, update, body):
+ self.setup = setup
+ self.condition = condition
+ self.update = update
+ self.body = body
+
+ def execute(self, ctx):
+ self.setup.eval(ctx)
+ while self.condition.eval(ctx).ToBoolean():
+ self.body.execute(ctx)
+ self.update.eval(ctx)
+
def getlist(t):
item = gettreeitem(t, 'length')
if item is None:
@@ -513,6 +541,12 @@
return Or(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'AND':
return And(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ elif tp == 'FOR':
+ setup = from_tree(gettreeitem(t, 'setup'))
+ condition = from_tree(gettreeitem(t, 'condition'))
+ update = from_tree(gettreeitem(t, 'update'))
+ body = from_tree(gettreeitem(t, 'body'))
+ return For(setup, condition, update, body)
elif tp == 'FUNCTION':
namesimb = gettreeitem(t, 'name')
name = None
@@ -549,6 +583,8 @@
return If(condition,thenPart,elsePart)
elif tp == 'IN':
return In(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ elif tp == 'INCREMENT':
+ return Increment(from_tree(gettreeitem(t, '0')))
elif tp == 'INDEX':
return Index(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'LIST':
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Thu Jan 11 12:31:17 2007
@@ -298,13 +298,20 @@
class W_Builtin(W_Root):
- def __init__(self, builtinfunction):
+ def __init__(self, builtinfunction, context=False, args=0):
#W_Object.__init__(self)
self.builtinfunction = builtinfunction
+ self.context = context
+ self.args = args
def Call(self, ctx, args=[], this = None):
- assert len(args) == 0
- return W_String(self.builtinfunction()) # ???
+ py_args = []
+ if self.context == True:
+ py_args.append(ctx)
+ for i in range(self.args):
+ py_args.append(args[i])
+ res = self.builtinfunction(*py_args)
+ return res
class W_List(W_Root):
def __init__(self, list_w):
Modified: pypy/dist/pypy/lang/js/jsparser.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsparser.py (original)
+++ pypy/dist/pypy/lang/js/jsparser.py Thu Jan 11 12:31:17 2007
@@ -26,6 +26,7 @@
pipe.stdin.close()
retval = pipe.stdout.read()
if not retval.startswith("{"):
+ print stripped_code
raise JsSyntaxError(retval)
return retval
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 12:31:17 2007
@@ -297,5 +297,22 @@
print(z)
"""]
,["3", "2"])
+
+ def test_for(self):
+ self.assert_prints("""
+ for (i=0; i<3; i=i+1) {
+ print(i);
+ }
+ print(i);
+ """, ["0","1","2","3"])
+
+ def test_eval(self):
+ self.assert_prints("""
+ var x = 2;
+ eval('x=x+1; print(x); z=2');
+ print(z);
+ """, ["3","2"])
+
+
From mwh at codespeak.net Thu Jan 11 12:31:32 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Thu, 11 Jan 2007 12:31:32 +0100 (CET)
Subject: [pypy-svn] r36465 - pypy/dist/pypy/config
Message-ID: <20070111113132.1EB2210088@code0.codespeak.net>
Author: mwh
Date: Thu Jan 11 12:31:26 2007
New Revision: 36465
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
(cfbolz, mwh)
When auto-building the config children for usemodules, look for the __init__.py
as well as the directory.
(I hate svn).
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Thu Jan 11 12:31:26 2007
@@ -5,7 +5,8 @@
modulepath = py.magic.autopath().dirpath().dirpath().join("module")
all_modules = [p.basename for p in modulepath.listdir()
- if p.check(dir=True, dotfile=False)]
+ if p.check(dir=True, dotfile=False)
+ and p.join('__init__.py').check()]
essential_modules = dict.fromkeys(
["exceptions", "_file", "sys", "__builtin__", "posix"]
From afayolle at codespeak.net Thu Jan 11 12:46:47 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Thu, 11 Jan 2007 12:46:47 +0100 (CET)
Subject: [pypy-svn] r36466 - pypy/dist/pypy/doc
Message-ID: <20070111114647.C198D1007C@code0.codespeak.net>
Author: afayolle
Date: Thu Jan 11 12:46:47 2007
New Revision: 36466
Modified:
pypy/dist/pypy/doc/README.Debian
Log:
updated after discussion with various sprint participants
Modified: pypy/dist/pypy/doc/README.Debian
==============================================================================
--- pypy/dist/pypy/doc/README.Debian (original)
+++ pypy/dist/pypy/doc/README.Debian Thu Jan 11 12:46:47 2007
@@ -9,9 +9,12 @@
- python2.4 (of course)
- python2.4-dev (for the C backend)
+- python-ctypes
+- libbz2-dev
- gcc (for the C backend)
- libgc-dev (boehm garbage collector)
-- mono-gmcs (CLI backend
+- mono-gmcs (CLI backend) NOTE: the version 1.2 currently in debian is
+ reported not to work, and 1.1.17 is recommended
- llvm-cfe (llvm backend)
- spidermonkey-bin (javascript backend)
- gcl-dev (for the common LISP backend) (to be confirmed)
@@ -24,7 +27,22 @@
Recommended packages include:
-- python-pygame (to display translation graphs)
+- python-pygame, graphviz (to display translation graphs)
+- ledit is nice too (to get readline in translated interpreters)
+
+
+The full apt-get line is:
+
+apt-get install python2.4-dev python-ctypes python-pygame graphviz libz2-dev libgc-dev gcc
+
+If you want to work on specific backends:
+
+apt-get install llvm-cfe
+apt-get install spidermonkey-bin
+apt-get install gcl-dev
+apt-get install mono-gmcs=1.1.17.1-1 # deb http://snapshot.debian.net/archive pool mono
+
+
Quirks and tips
---------------
From cfbolz at codespeak.net Thu Jan 11 12:50:29 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu, 11 Jan 2007 12:50:29 +0100 (CET)
Subject: [pypy-svn] r36467 - pypy/dist/pypy/bin
Message-ID: <20070111115029.0766510091@code0.codespeak.net>
Author: cfbolz
Date: Thu Jan 11 12:50:28 2007
New Revision: 36467
Modified:
pypy/dist/pypy/bin/jscompile.py
Log:
have --help working with jscompile
Modified: pypy/dist/pypy/bin/jscompile.py
==============================================================================
--- pypy/dist/pypy/bin/jscompile.py (original)
+++ pypy/dist/pypy/bin/jscompile.py Thu Jan 11 12:50:28 2007
@@ -13,17 +13,17 @@
from pypy.config.config import Config, to_optparse
-def process_options(argv):
+def process_options():
jsconfig = Config(js_optiondescr)
- parser = to_optparse(jsconfig)
+ parser = to_optparse(jsconfig, parserkwargs={"usage": __doc__})
parser.disable_interspersed_args()
- options, args = parser.parse_args(argv)
+ options, args = parser.parse_args()
return args, jsconfig
if __name__ == '__main__':
- args, jsconfig = process_options(sys.argv)
+ args, jsconfig = process_options()
curdir = os.getcwd()
if curdir not in sys.path:
sys.path.insert(0, curdir)
print args
- rpython2javascript_main(args[1:], jsconfig)
+ rpython2javascript_main(args, jsconfig)
From fijal at codespeak.net Thu Jan 11 12:54:03 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 12:54:03 +0100 (CET)
Subject: [pypy-svn] r36468 - pypy/dist/pypy/bin
Message-ID: <20070111115403.BA62E10094@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 12:54:01 2007
New Revision: 36468
Modified:
pypy/dist/pypy/bin/jscompile.py
Log:
Fix the args.
Modified: pypy/dist/pypy/bin/jscompile.py
==============================================================================
--- pypy/dist/pypy/bin/jscompile.py (original)
+++ pypy/dist/pypy/bin/jscompile.py Thu Jan 11 12:54:01 2007
@@ -25,5 +25,4 @@
curdir = os.getcwd()
if curdir not in sys.path:
sys.path.insert(0, curdir)
- print args
rpython2javascript_main(args, jsconfig)
From niko at codespeak.net Thu Jan 11 13:15:18 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 13:15:18 +0100 (CET)
Subject: [pypy-svn] r36471 - in pypy/dist/pypy/translator/jvm: . src test
Message-ID: <20070111121518.88F161008F@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 13:15:17 2007
New Revision: 36471
Added:
pypy/dist/pypy/translator/jvm/test/test_list.py
pypy/dist/pypy/translator/jvm/test/test_pbc.py
Modified:
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/metavm.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/opcodes.py
pypy/dist/pypy/translator/jvm/src/PyPy.java
pypy/dist/pypy/translator/jvm/typesystem.py
Log:
(antocuni, niko)
progress towards test_pbc working: implemented lists, toString(),
generic support, and some other stuff
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Thu Jan 11 13:15:17 2007
@@ -2,9 +2,7 @@
from pypy.translator.jvm import generator as jvmgen
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.typesystem import \
- jInt, jVoid, jStringBuilder, jString, jPyPy, jChar
-
-jStringBuilder = jvmtype.jStringBuilder
+ jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject
# ______________________________________________________________________
# Mapping of built-in OOTypes to JVM types
@@ -81,6 +79,10 @@
jvmgen.PYPYJAVA, "ll_build", (jStringBuilder,), jOOString)
built_in_methods = {
+
+ # Note: String and StringBuilder are rebound in ootype, and thus
+ # .__class__ is required
+
(ootype.StringBuilder.__class__, "ll_allocate"):
jvmgen.Method.v(jStringBuilder, "ensureCapacity", (jInt,), jVoid),
@@ -91,6 +93,25 @@
jvmgen.Method.s(jPyPy, "ll_append", (jStringBuilder, jString), jVoid),
(ootype.StringBuilder.__class__, "ll_build"):
- _ll_build_method()
-
+ _ll_build_method(),
+
+ (ootype.List, "ll_length"):
+ jvmgen.Method.v(jArrayList, "size", (), jInt),
+
+ (ootype.List, "ll_getitem_fast"):
+ jvmgen.Method.v(jArrayList, "get", (jInt,), jObject),
+
+ (ootype.List, "ll_setitem_fast"):
+ jvmgen.Method.s(jPyPy, "ll_setitem_fast",
+ (jArrayList, jInt, jObject), jVoid),
+
+ (ootype.List, "_ll_resize_ge"):
+ jvmgen.Method.s(jPyPy, "_ll_resize_ge", (jArrayList, jInt), jVoid),
+
+ (ootype.List, "_ll_resize_le"):
+ jvmgen.Method.s(jPyPy, "_ll_resize_le", (jArrayList, jInt), jVoid),
+
+ (ootype.List, "_ll_resize"):
+ jvmgen.Method.s(jPyPy, "_ll_resize", (jArrayList, jInt), jVoid),
+
}
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Thu Jan 11 13:15:17 2007
@@ -241,39 +241,32 @@
# Returns a method that prints details about the value out to
# stdout. Should generalize to make it allow for stderr as well.
- _type_printing_methods = {
- ootype.Signed:jvmgen.PYPYDUMPINT,
+ _toString_methods = {
+ ootype.Signed:jvmgen.INTTOSTRINGI,
ootype.Unsigned:jvmgen.PYPYDUMPUINT,
- ootype.SignedLongLong:jvmgen.PYPYDUMPLONG,
- ootype.Float:jvmgen.PYPYDUMPDOUBLE,
+ ootype.SignedLongLong:jvmgen.LONGTOSTRINGL,
+ ootype.Float:jvmgen.DOUBLETOSTRINGD,
ootype.Bool:jvmgen.PYPYDUMPBOOLEAN,
- ootype.Class:jvmgen.PYPYDUMPOBJECT,
- ootype.String:jvmgen.PYPYDUMPSTRING,
- ootype.StringBuilder:jvmgen.PYPYDUMPOBJECT,
ootype.Void:jvmgen.PYPYDUMPVOID,
- ootype.Char:jvmgen.PYPYDUMPCHAR
+ ootype.Char:jvmgen.CHARTOSTRINGC,
+ ootype.String:jvmgen.PYPYESCAPEDSTRING,
}
- def generate_dump_method_for_ootype(self, OOTYPE):
+ def generate_toString_method_for_ootype(self, OOTYPE):
"""
Assuming than an instance of type OOTYPE is pushed on the
- stack, returns a Method object that you can invoke. This
- method will require that you also push an integer (usually 0)
- that represents the indentation, and then invoke it. i.e., you
- can do something like:
+ stack, returns a Method object that you can invoke. This method
+ will return a string representing the contents of that type.
+ Do something like:
+
> gen.load(var)
- > mthd = db.generate_dump_method_for_ootype(var.concretetype)
- > gen.emit(jvmgen.ICONST, 0)
+ > mthd = db.generate_toString_method_for_ootype(var.concretetype)
> mthd.invoke(gen)
to print the value of 'var'.
"""
- if OOTYPE in self._type_printing_methods:
- return self._type_printing_methods[OOTYPE]
- pclass = self.pending_class(OOTYPE)
- assert hasattr(pclass, 'dump_method'), "No dump_method for %r" % (OOTYPE, )
- return pclass.dump_method.method()
+ return self._toString_methods.get(OOTYPE, jvmgen.OBJTOSTRING)
# _________________________________________________________________
# Type translation functions
@@ -310,7 +303,8 @@
# will return a JvmBuiltInType based on the value
ootype_to_builtin = {
ootype.String: jvmtype.jString,
- ootype.StringBuilder: jvmtype.jStringBuilder
+ ootype.StringBuilder: jvmtype.jStringBuilder,
+ ootype.List: jvmtype.jArrayList
}
def lltype_to_cts(self, OOT):
@@ -324,6 +318,9 @@
return jObject
if OOT in self.ootype_to_builtin:
return JvmBuiltInType(self, self.ootype_to_builtin[OOT], OOT)
+ if OOT.__class__ in self.ootype_to_builtin:
+ return JvmBuiltInType(
+ self, self.ootype_to_builtin[OOT.__class__], OOT)
# Handle non-built-in-types:
if isinstance(OOT, ootype.Instance):
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 13:15:17 2007
@@ -6,7 +6,8 @@
from pypy.translator.jvm.typesystem import \
JvmType, jString, jInt, jLong, jDouble, jBool, jString, \
jPyPy, jVoid, jMath, desc_for_method, jPrintStream, jClass, jChar, \
- jObject, jByteArray, jPyPyExcWrap
+ jObject, jByteArray, jPyPyExcWrap, jIntegerClass, jLongClass, \
+ jDoubleClass, jCharClass, jStringBuilder
# ___________________________________________________________________________
# Miscellaneous helper functions
@@ -320,12 +321,19 @@
self.descriptor = desc_for_method(argtypesdesc, rettypedesc)
def invoke(self, gen):
gen._instr(self.opcode, self)
+ def is_static(self):
+ return self.opcode == INVOKESTATIC
def jasmin_syntax(self):
return "%s/%s%s" % (self.class_name.replace('.','/'),
self.method_name,
self.descriptor)
OBJHASHCODE = Method.v(jObject, 'hashCode', (), jInt)
+OBJTOSTRING = Method.v(jObject, 'toString', (), jString)
+INTTOSTRINGI = Method.s(jIntegerClass, 'toString', (jInt,), jString)
+LONGTOSTRINGL = Method.s(jLongClass, 'toString', (jLong,), jString)
+DOUBLETOSTRINGD = Method.s(jDoubleClass, 'toString', (jDouble,), jString)
+CHARTOSTRINGC = Method.s(jCharClass, 'toString', (jChar,), jString)
MATHIABS = Method.s(jMath, 'abs', (jInt,), jInt)
MATHLABS = Method.s(jMath, 'abs', (jLong,), jLong)
MATHDABS = Method.s(jMath, 'abs', (jDouble,), jDouble)
@@ -333,6 +341,8 @@
PRINTSTREAMPRINTSTR = Method.v(jPrintStream, 'print', (jString,), jVoid)
CLASSFORNAME = Method.s(jClass, 'forName', (jString,), jClass)
CLASSISASSIGNABLEFROM = Method.v(jClass, 'isAssignableFrom', (jClass,), jBool)
+PYPYAPPEND = Method.s(jPyPy, 'append',
+ (jStringBuilder, jString), jVoid)
PYPYUINTCMP = Method.s(jPyPy, 'uint_cmp', (jInt,jInt,), jInt)
PYPYULONGCMP = Method.s(jPyPy, 'ulong_cmp', (jLong,jLong), jInt)
PYPYUINTTODOUBLE = Method.s(jPyPy, 'uint_to_double', (jInt,), jDouble)
@@ -345,16 +355,11 @@
PYPYSTRTOBOOL = Method.s(jPyPy, 'str_to_bool', (jString,), jBool)
PYPYSTRTODOUBLE = Method.s(jPyPy, 'str_to_double', (jString,), jDouble)
PYPYSTRTOCHAR = Method.s(jPyPy, 'str_to_char', (jString,), jChar)
-PYPYDUMPINDENTED = Method.s(jPyPy, 'dump_indented', (jInt,jString,), jVoid)
-PYPYDUMPINT = Method.s(jPyPy, 'dump_int', (jInt,jInt), jVoid)
-PYPYDUMPCHAR = Method.s(jPyPy, 'dump_char', (jChar,jInt), jVoid)
-PYPYDUMPUINT = Method.s(jPyPy, 'dump_uint', (jInt,jInt), jVoid)
-PYPYDUMPLONG = Method.s(jPyPy, 'dump_long', (jLong,jInt), jVoid)
-PYPYDUMPDOUBLE = Method.s(jPyPy, 'dump_double', (jDouble,jInt), jVoid)
-PYPYDUMPSTRING = Method.s(jPyPy, 'dump_string', (jString,jInt), jVoid)
-PYPYDUMPBOOLEAN = Method.s(jPyPy, 'dump_boolean', (jBool,jInt), jVoid)
-PYPYDUMPOBJECT = Method.s(jPyPy, 'dump_object', (jObject,jInt,), jVoid)
-PYPYDUMPVOID = Method.s(jPyPy, 'dump_void', (jInt,), jVoid)
+PYPYDUMP = Method.s(jPyPy, 'dump', (jString,), jVoid)
+PYPYDUMPBOOLEAN = Method.s(jPyPy, 'dump_boolean', (jBool,), jString)
+PYPYDUMPUINT = Method.s(jPyPy, 'dump_uint', (jInt,), jString)
+PYPYDUMPVOID = Method.s(jPyPy, 'dump_void', (), jString)
+PYPYESCAPEDSTRING = Method.s(jPyPy, 'escaped_string', (jString,), jString)
PYPYDUMPEXCWRAPPER = Method.s(jPyPy, 'dump_exc_wrapper', (jObject,), jVoid)
PYPYRUNTIMENEW = Method.s(jPyPy, 'RuntimeNew', (jClass,), jObject)
PYPYSTRING2BYTES = Method.s(jPyPy, 'string2bytes', (jString,), jByteArray)
@@ -653,6 +658,21 @@
jtype, jidx = self.curfunc.function_arguments[index]
self.load_jvm_var(jtype, jidx)
+ def box_value(self, jscalartype):
+ """ Assuming that an value of type jscalartype is on the stack,
+ boxes it into an Object. """
+ jclasstype = jscalartype.box_type
+ jmethod = Method.s(jclasstype, 'valueOf', (jscalartype,), jclasstype)
+ self.emit(jmethod)
+
+ def unbox_value(self, jscalartype):
+ """ Assuming that a boxed value of type jscalartype is on the stack,
+ unboxes it. """
+ jclasstype = jscalartype.box_type
+ jmethod = Method.v(
+ jclasstype, jscalartype.unbox_method, (), jscalartype)
+ self.emit(jmethod)
+
# __________________________________________________________________
# Exception Handling
@@ -732,6 +752,9 @@
if isinstance(instr, Method):
return instr.invoke(self)
+ if isinstance(instr, Field):
+ return instr.load(self)
+
raise Exception("Unknown object in call to emit(): "+repr(instr))
def _var_data(self, v):
@@ -774,6 +797,9 @@
def downcast(self, TYPE):
jtype = self.db.lltype_to_cts(TYPE)
+ self.downcast_jtype(jtype)
+
+ def downcast_jtype(self, jtype):
self._instr(CHECKCAST, jtype)
def instanceof(self, TYPE):
Modified: pypy/dist/pypy/translator/jvm/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/metavm.py (original)
+++ pypy/dist/pypy/translator/jvm/metavm.py Thu Jan 11 13:15:17 2007
@@ -1,5 +1,5 @@
from pypy.translator.oosupport.metavm import MicroInstruction
-
+from pypy.translator.jvm.typesystem import JvmScalarType, JvmClassType
class _IndirectCall(MicroInstruction):
def render(self, gen, op):
@@ -8,3 +8,52 @@
gen.emit(method)
IndirectCall = _IndirectCall()
+class _JvmCallMethod(MicroInstruction):
+
+ def _invoke_method(self, gen, db, jmethod, jactargs, args, jactres, res):
+ for arg, jmthdty in zip(args, jactargs):
+ jargty = db.lltype_to_cts(arg.concretetype)
+
+ # Load the argument on the stack:
+ gen.load(arg)
+
+ # Perform any boxing required:
+ if (isinstance(jargty, JvmScalarType) and
+ not isinstance(jmthdty, JvmScalarType)):
+ gen.box_value(jargty)
+
+ gen.emit(jmethod)
+
+ jresty = db.lltype_to_cts(res.concretetype)
+
+ if (isinstance(jresty, JvmScalarType) and
+ not isinstance(jactres, JvmScalarType)):
+ # Perform any un-boxing required:
+ gen.downcast_jtype(jresty.box_type)
+ gen.unbox_value(jresty)
+ elif jresty != jactres:
+ # Perform any casting required:
+ gen.downcast(res.concretetype)
+
+ def render(self, gen, op):
+
+ method = op.args[0] # a FlowConstant string...
+ this = op.args[1]
+
+ # Locate the java method we will be invoking:
+ thisjtype = gen.db.lltype_to_cts(this.concretetype)
+ jmethod = thisjtype.lookup_method(method.value)
+
+ # Ugly: if jmethod ends up being a static method, then
+ # peel off the first argument
+ jactargs = jmethod.argument_types
+ if jmethod.is_static():
+ jactargs = jactargs[1:]
+
+ # Iterate through the arguments, inserting casts etc as required
+ gen.load(this)
+ self._invoke_method(gen, gen.db, jmethod,
+ jactargs, op.args[2:],
+ jmethod.return_type, op.result)
+
+JvmCallMethod = _JvmCallMethod()
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 13:15:17 2007
@@ -14,11 +14,12 @@
"""
+from pypy.objspace.flow import model as flowmodel
from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.ootypesystem import ootype
+from pypy.rpython.ootypesystem import ootype, rclass
from pypy.translator.jvm.typesystem import \
JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, jPyPyMain, \
- jObject, JvmType
+ jObject, JvmType, jStringBuilder
from pypy.translator.jvm.opcodes import opcodes
from pypy.translator.jvm.option import getoption
from pypy.translator.oosupport.function import Function as OOFunction
@@ -112,15 +113,15 @@
#
if self.print_result:
done_printing = gen.unique_label('done_printing')
- gen.emit(jvmgen.ICONST, 0)
RESOOTYPE = self.graph.getreturnvar().concretetype
- dumpmethod = self.db.generate_dump_method_for_ootype(RESOOTYPE)
- dumpmethod.invoke(gen)
+ dumpmethod = self.db.generate_toString_method_for_ootype(RESOOTYPE)
+ gen.emit(dumpmethod) # generate the string
+ gen.emit(jvmgen.PYPYDUMP) # dump to stdout
gen.goto(done_printing)
gen.end_try()
gen.begin_catch(jObject)
- gen.emit(jvmgen.PYPYDUMPEXCWRAPPER)
+ gen.emit(jvmgen.PYPYDUMPEXCWRAPPER) # dumps to stdout
gen.end_catch()
gen.mark(done_printing)
@@ -204,13 +205,37 @@
self.ilasm.end_try()
def begin_catch(self, llexitcase):
- unimplemented
-
- def end_catch(self, llexitcase):
- unimplemented
+ ll_meta_exc = llexitcase
+ ll_exc = ll_meta_exc._inst.class_._INSTANCE
+ cts_exc = self.cts.lltype_to_cts(ll_exc)
+ self.ilasm.begin_catch(cts_exc)
+
+ def end_catch(self, exit_lbl):
+ self.ilasm.goto(exit_lbl)
+ self.ilasm.end_catch()
def store_exception_and_link(self, link):
- unimplemented
+ if self._is_raise_block(link.target):
+ # the exception value is on the stack, use it as the 2nd target arg
+ assert len(link.args) == 2
+ assert len(link.target.inputargs) == 2
+ self.ilasm.store(link.target.inputargs[1])
+ else:
+ # the exception value is on the stack, store it in the proper place
+ if isinstance(link.last_exception, flowmodel.Variable):
+ self.ilasm.dup(jObject)
+ self.ilasm.store(link.last_exc_value)
+ fld = jvmgen.Field(
+ self.db.lltype_to_cts(rclass.CLASSTYPE).name,
+ 'meta',
+ self.db.lltype_to_cts(rclass.OBJECT),
+ False,
+ rclass.OBJECT)
+ self.ilasm.emit(fld)
+ self.ilasm.store(link.last_exception)
+ else:
+ self.ilasm.store(link.last_exc_value)
+ self._setup_link(link)
def render_return_block(self, block):
return_var = block.inputargs[0]
@@ -414,57 +439,45 @@
self.db = db
self.OOCLASS = OOCLASS
self.clsobj = clsobj
- self.name = "_pypy_dump"
- self.jargtypes = [clsobj, jInt]
- self.jrettype = jVoid
-
- def method(self):
- """ Returns a jvmgen.Method that can invoke this function """
- return jvmgen.Method.v(
- self.clsobj, self.name, self.jargtypes[1:], self.jrettype)
-
- def _increase_indent(self, gen):
- gen.load_jvm_var(jInt, 1)
- gen.emit(jvmgen.ICONST, 2)
- gen.emit(jvmgen.IADD)
- gen.store_jvm_var(jInt, 1)
-
- def _print_field_value(self, gen, fieldnm, FIELDOOTY):
- gen.load_this_ptr()
+ self.name = "toString"
+ self.jargtypes = [clsobj]
+ self.jrettype = jString
+
+ def _print_field_value(self, fieldnm, FIELDOOTY):
+ self.gen.emit(jvmgen.DUP)
+ self.gen.load_this_ptr()
fieldobj = self.clsobj.lookup_field(fieldnm)
- fieldobj.load(gen)
- gen.load_jvm_var(jInt, 1)
- dumpmethod = self.db.generate_dump_method_for_ootype(FIELDOOTY)
- gen.emit(dumpmethod)
+ fieldobj.load(self.gen)
+ dumpmethod = self.db.generate_toString_method_for_ootype(FIELDOOTY)
+ self.gen.emit(dumpmethod)
+ self.gen.emit(jvmgen.PYPYAPPEND)
+
+ def _print(self, str):
+ self.gen.emit(jvmgen.DUP)
+ self.gen.load_string(str)
+ self.gen.emit(jvmgen.PYPYAPPEND)
def render(self, gen):
+ self.gen = gen
gen.begin_function(
self.name, (), self.jargtypes, self.jrettype, static=False)
- def genprint(str, unoffset=0):
- gen.load_jvm_var(jInt, 1)
- if unoffset:
- gen.emit(jvmgen.ICONST, unoffset)
- gen.emit(jvmgen.ISUB)
- gen.load_string(str)
- jvmgen.PYPYDUMPINDENTED.invoke(gen)
-
- self._render_guts(gen, genprint)
-
- gen.emit(jvmgen.RETURN.for_type(jVoid))
+ gen.new_with_jtype(jStringBuilder)
+ self._render_guts(gen)
+ gen.emit(jvmgen.OBJTOSTRING)
+ gen.emit(jvmgen.RETURN.for_type(jString))
gen.end_function()
+ self.gen = None
class InstanceDumpMethod(BaseDumpMethod):
- def _render_guts(self, gen, genprint):
+ def _render_guts(self, gen):
clsobj = self.clsobj
+ genprint = self._print
# Start the dump
genprint("InstanceWrapper([")
- # Increment the indent
- self._increase_indent(gen)
-
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
if FIELDOOTY is ootype.Void: continue
@@ -475,24 +488,31 @@
print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
# Print the value of the field:
- self._print_field_value(gen, fieldnm, FIELDOOTY)
+ self._print_field_value(fieldnm, FIELDOOTY)
genprint(")")
- # Decrement indent and dump close
- genprint("])", 2)
+ # Dump close
+ genprint("])")
class RecordDumpMethod(BaseDumpMethod):
- def _render_guts(self, gen, genprint):
+ def _render_guts(self, gen):
clsobj = self.clsobj
+ genprint = self._print
+
+ # We only render records that represent tuples:
+ # In that case, the field names look like item0, item1, etc
+ # Otherwise, we just do nothing... this is because we
+ # never return records that do not represent tuples from
+ # a testing function
+ for f_name in self.OOCLASS._fields:
+ if not f_name.startswith('item'):
+ return
# Start the dump
genprint("StructTuple((")
- # Increment the indent
- self._increase_indent(gen)
-
numfields = len(self.OOCLASS._fields)
for i in range(numfields):
f_name = 'item%d' % i
@@ -501,11 +521,11 @@
continue
# Print the value of the field:
- self._print_field_value(gen, f_name, FIELD_TYPE)
+ self._print_field_value(f_name, FIELD_TYPE)
genprint(',')
# Decrement indent and dump close
- genprint("))", 2)
+ genprint("))")
class ConstantStringDumpMethod(BaseDumpMethod):
""" Just prints out a string """
@@ -514,5 +534,6 @@
BaseDumpMethod.__init__(self, None, None, clsobj)
self.constant_string = str
- def _render_guts(self, gen, genprint):
+ def _render_guts(self, gen):
+ genprint = self._print
genprint("'" + self.constant_string + "'")
Modified: pypy/dist/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/opcodes.py (original)
+++ pypy/dist/pypy/translator/jvm/opcodes.py Thu Jan 11 13:15:17 2007
@@ -7,9 +7,9 @@
from pypy.translator.oosupport.metavm import \
PushArg, PushAllArgs, StoreResult, InstructionList, New, DoNothing, Call,\
- SetField, GetField, CallMethod, DownCast, RuntimeNew, OOString, CastTo
+ SetField, GetField, DownCast, RuntimeNew, OOString, CastTo
from pypy.translator.jvm.metavm import \
- IndirectCall
+ IndirectCall, JvmCallMethod
import pypy.translator.jvm.generator as jvmgen
def _check_zer(op):
@@ -28,7 +28,7 @@
'runtimenew': [RuntimeNew, StoreResult],
'oosetfield': [SetField],
'oogetfield': [GetField, StoreResult],
- 'oosend': [CallMethod, StoreResult],
+ 'oosend': [JvmCallMethod, StoreResult],
'ooupcast': DoNothing,
'oodowncast': [DownCast, StoreResult],
'oois': 'ref_is_eq',
@@ -51,6 +51,8 @@
#'gc__collect': 'call void class [mscorlib]System.GC::Collect()',
#'resume_point': Ignore,
+ 'debug_assert': [], # TODO: implement?
+
# __________ numeric operations __________
'bool_not': 'logical_not',
Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java Thu Jan 11 13:15:17 2007
@@ -188,47 +188,30 @@
// Used in testing:
- public static void dump_indented(int indent, String text) {
- for (int i = 0; i < indent; i++)
- System.out.print(" ");
+ public static void dump(String text) {
System.out.println(text);
}
- public static void dump_void(int indent) {
+ public static String dump_void() {
+ return "None";
}
- public static void dump_int(int i, int indent) {
- dump_indented(indent, Integer.toString(i));
- }
-
- public static void dump_char(char c, int indent) {
- dump_indented(indent, "'"+c+"'");
- }
-
- public static void dump_uint(int i, int indent) {
+ public static String dump_uint(int i) {
if (i >= 0)
- dump_indented(indent, Integer.toString(i));
+ return Integer.toString(i);
else {
int loword = i & 0xFFFF;
int hiword = i >>> 16;
long res = loword + (hiword*0xFFFF);
- dump_indented(indent, Long.toString(res));
+ return Long.toString(res);
}
}
- public static void dump_boolean(boolean l, int indent) {
+ public static String dump_boolean(boolean l) {
if (l)
- dump_indented(indent, "True");
+ return "True";
else
- dump_indented(indent, "False");
- }
-
- public static void dump_long(long l, int indent) {
- dump_indented(indent, Long.toString(l));
- }
-
- public static void dump_double(double d, int indent) {
- dump_indented(indent, Double.toString(d));
+ return "False";
}
public static void _append_char(StringBuffer sb, char c) {
@@ -238,17 +221,6 @@
sb.append(c);
}
- public static void dump_string(byte[] b, int indent) {
- StringBuffer sb = new StringBuffer();
- sb.append('"');
- for (byte _c : b) {
- char c = (char)_c;
- _append_char(sb, c);
- }
- sb.append('"');
- dump_indented(indent, sb.toString());
- }
-
public static String escaped_string(String b) {
StringBuffer sb = new StringBuffer();
sb.append('"');
@@ -260,14 +232,6 @@
return sb.toString();
}
- public static void dump_string(String b, int indent) {
- dump_indented(indent, escaped_string(b));
- }
-
- public static void dump_object(Object o, int indent) {
- dump_indented(indent, o.toString());
- }
-
// used in running unit tests
// not really part of the dump_XXX set of objects, hence the lack
// of an indent parameter
@@ -277,7 +241,7 @@
sb.append("ExceptionWrapper(");
sb.append(escaped_string(clnm));
sb.append(")");
- dump_indented(0, sb.toString());
+ dump(sb.toString());
}
// ----------------------------------------------------------------------
@@ -330,6 +294,11 @@
return s.getBytes();
}
+ public static void append(StringBuilder sb, String s) {
+ // avoid the annoying return value of StringBuilder.append
+ sb.append(s);
+ }
+
// ----------------------------------------------------------------------
// OOString support
@@ -395,6 +364,34 @@
*/
// ----------------------------------------------------------------------
+ // Lists
+
+ public static void ll_setitem_fast(ArrayList self, int index, Object val)
+ {
+ // need a wrapper because set returns the old value
+ self.set(index, val);
+ }
+
+ public static void _ll_resize_ge(ArrayList self, int length) {
+ while (self.size() < length) {
+ self.add(null);
+ }
+ }
+
+ public static void _ll_resize_le(ArrayList self, int length) {
+ while (self.size() > length) {
+ self.remove(self.size()-1);
+ }
+ }
+
+ public static void _ll_resize(ArrayList self, int length) {
+ if (length > self.size())
+ _ll_resize_ge(self, length);
+ else if (length < self.size())
+ _ll_resize_le(self, length);
+ }
+
+ // ----------------------------------------------------------------------
// Self Test
public static int __counter = 0, __failures = 0;
Added: pypy/dist/pypy/translator/jvm/test/test_list.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/test/test_list.py Thu Jan 11 13:15:17 2007
@@ -0,0 +1,10 @@
+import py
+from pypy.translator.jvm.test.runtest import JvmTest
+from pypy.rpython.test.test_rlist import BaseTestRlist
+
+class TestJvmList(JvmTest, BaseTestRlist):
+ #def test_recursive(self):
+ # py.test.skip("JVM doesn't support recursive lists")
+ #
+ def test_getitem_exc(self):
+ py.test.skip('fixme!')
Added: pypy/dist/pypy/translator/jvm/test/test_pbc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/test/test_pbc.py Thu Jan 11 13:15:17 2007
@@ -0,0 +1,6 @@
+import py
+from pypy.translator.jvm.test.runtest import JvmTest
+from pypy.rpython.test.test_rpbc import BaseTestRPBC
+
+class TestCliPBC(JvmTest, BaseTestRPBC):
+ pass
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Thu Jan 11 13:15:17 2007
@@ -128,24 +128,6 @@
def __repr__(self):
return "%s<%s>" % (self.__class__.__name__, self.descriptor)
-class JvmScalarType(JvmType):
- """
- Subclass used for all scalar type instances.
- """
- def __init__(self, descrstr):
- JvmType.__init__(self, JvmTypeDescriptor(descrstr))
- def lookup_field(self, fieldnm):
- raise KeyError(fieldnm) # Scalar objects have no fields
- def lookup_method(self, methodnm):
- raise KeyError(methodnm) # Scalar objects have no methods
-
-jVoid = JvmScalarType('V')
-jInt = JvmScalarType('I')
-jLong = JvmScalarType('J')
-jBool = JvmScalarType('Z')
-jDouble = JvmScalarType('D')
-jByte = JvmScalarType('B')
-jChar = JvmScalarType('C')
class JvmClassType(JvmType):
"""
Base class used for all class instances. Kind of an abstract class;
@@ -161,6 +143,10 @@
def lookup_method(self, methodnm):
raise KeyError(fieldnm) # we treat as opaque type
+jIntegerClass = JvmClassType('java.lang.Integer')
+jLongClass = JvmClassType('java.lang.Long')
+jDoubleClass = JvmClassType('java.lang.Double')
+jCharClass = JvmClassType('java.lang.Char')
jThrowable = JvmClassType('java.lang.Throwable')
jObject = JvmClassType('java.lang.Object')
jString = JvmClassType('java.lang.String')
@@ -172,11 +158,32 @@
jPrintStream = JvmClassType('java.io.PrintStream')
jMath = JvmClassType('java.lang.Math')
jList = JvmClassType('java.util.List')
+jArrayList = JvmClassType('java.util.ArrayList')
jPyPy = JvmClassType('pypy.PyPy')
jPyPyExcWrap = JvmClassType('pypy.ExceptionWrapper')
jPyPyConst = JvmClassType('pypy.Constant')
jPyPyMain = JvmClassType('pypy.Main')
+class JvmScalarType(JvmType):
+ """
+ Subclass used for all scalar type instances.
+ """
+ def __init__(self, descrstr, boxtype, unboxmethod):
+ JvmType.__init__(self, JvmTypeDescriptor(descrstr))
+ self.box_type = boxtype
+ self.unbox_method = unboxmethod
+ def lookup_field(self, fieldnm):
+ raise KeyError(fieldnm) # Scalar objects have no fields
+ def lookup_method(self, methodnm):
+ raise KeyError(methodnm) # Scalar objects have no methods
+jVoid = JvmScalarType('V', None, None)
+jInt = JvmScalarType('I', jIntegerClass, 'intValue')
+jLong = JvmScalarType('J', jLongClass, 'longValue')
+jBool = JvmScalarType('Z', jIntegerClass, 'intValue')
+jDouble = JvmScalarType('D', jDoubleClass, 'doubleValue')
+jByte = JvmScalarType('B', jIntegerClass, 'intValue')
+jChar = JvmScalarType('C', jIntegerClass, 'intValue')
+
class JvmArrayType(JvmType):
"""
Subclass used for all array instances.
From mwh at codespeak.net Thu Jan 11 13:15:57 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Thu, 11 Jan 2007 13:15:57 +0100 (CET)
Subject: [pypy-svn] r36472 - pypy/dist/pypy/bin
Message-ID: <20070111121557.5FB0C10093@code0.codespeak.net>
Author: mwh
Date: Thu Jan 11 13:15:54 2007
New Revision: 36472
Modified:
pypy/dist/pypy/bin/buildserver.py
pypy/dist/pypy/bin/startcompile.py
Log:
(mwh, cfbolz)
use /usr/bin/env python, not /usr/bin/python in build server related scripts.
if a build result is already available, give a hint as to on which machine it
can be found.
Modified: pypy/dist/pypy/bin/buildserver.py
==============================================================================
--- pypy/dist/pypy/bin/buildserver.py (original)
+++ pypy/dist/pypy/bin/buildserver.py Thu Jan 11 13:15:54 2007
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
import autopath
import py
Modified: pypy/dist/pypy/bin/startcompile.py
==============================================================================
--- pypy/dist/pypy/bin/startcompile.py (original)
+++ pypy/dist/pypy/bin/startcompile.py Thu Jan 11 13:15:54 2007
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/env python
import autopath
from pypy.tool.build.bin import path
@@ -87,7 +87,7 @@
ispath, data = data
if ispath:
print ('a suitable result is already available, you can find it '
- 'at "%s"' % (data,))
+ 'at "%s" on %s' % (data, config.server))
else:
print data
print 'you will be mailed once it\'s ready'
From antocuni at codespeak.net Thu Jan 11 13:43:54 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 11 Jan 2007 13:43:54 +0100 (CET)
Subject: [pypy-svn] r36473 - pypy/dist/pypy/doc
Message-ID: <20070111124354.E33E610080@code0.codespeak.net>
Author: antocuni
Date: Thu Jan 11 13:43:53 2007
New Revision: 36473
Modified:
pypy/dist/pypy/doc/README.Debian
Log:
Modified: pypy/dist/pypy/doc/README.Debian
==============================================================================
--- pypy/dist/pypy/doc/README.Debian (original)
+++ pypy/dist/pypy/doc/README.Debian Thu Jan 11 13:43:53 2007
@@ -14,7 +14,7 @@
- gcc (for the C backend)
- libgc-dev (boehm garbage collector)
- mono-gmcs (CLI backend) NOTE: the version 1.2 currently in debian is
- reported not to work, and 1.1.17 is recommended
+ reported to work only partially, and 1.1.17 is recommended
- llvm-cfe (llvm backend)
- spidermonkey-bin (javascript backend)
- gcl-dev (for the common LISP backend) (to be confirmed)
From niko at codespeak.net Thu Jan 11 13:45:47 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 13:45:47 +0100 (CET)
Subject: [pypy-svn] r36474 - in pypy/dist/pypy/translator: jvm jvm/src
jvm/test oosupport
Message-ID: <20070111124547.1423F10080@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 13:45:45 2007
New Revision: 36474
Modified:
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/src/PyPy.java
pypy/dist/pypy/translator/jvm/test/runtest.py
pypy/dist/pypy/translator/jvm/typesystem.py
pypy/dist/pypy/translator/oosupport/constant.py
pypy/dist/pypy/translator/oosupport/metavm.py
Log:
(antocuni, niko)
1. fix boxing in constant preparation
2. char dump and quoting
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Thu Jan 11 13:45:45 2007
@@ -248,7 +248,7 @@
ootype.Float:jvmgen.DOUBLETOSTRINGD,
ootype.Bool:jvmgen.PYPYDUMPBOOLEAN,
ootype.Void:jvmgen.PYPYDUMPVOID,
- ootype.Char:jvmgen.CHARTOSTRINGC,
+ ootype.Char:jvmgen.PYPYESCAPEDCHAR,
ootype.String:jvmgen.PYPYESCAPEDSTRING,
}
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 13:45:45 2007
@@ -7,7 +7,7 @@
JvmType, jString, jInt, jLong, jDouble, jBool, jString, \
jPyPy, jVoid, jMath, desc_for_method, jPrintStream, jClass, jChar, \
jObject, jByteArray, jPyPyExcWrap, jIntegerClass, jLongClass, \
- jDoubleClass, jCharClass, jStringBuilder
+ jDoubleClass, jCharClass, jStringBuilder, JvmScalarType
# ___________________________________________________________________________
# Miscellaneous helper functions
@@ -359,6 +359,7 @@
PYPYDUMPBOOLEAN = Method.s(jPyPy, 'dump_boolean', (jBool,), jString)
PYPYDUMPUINT = Method.s(jPyPy, 'dump_uint', (jInt,), jString)
PYPYDUMPVOID = Method.s(jPyPy, 'dump_void', (), jString)
+PYPYESCAPEDCHAR = Method.s(jPyPy, 'escaped_char', (jChar,), jString)
PYPYESCAPEDSTRING = Method.s(jPyPy, 'escaped_string', (jString,), jString)
PYPYDUMPEXCWRAPPER = Method.s(jPyPy, 'dump_exc_wrapper', (jObject,), jVoid)
PYPYRUNTIMENEW = Method.s(jPyPy, 'RuntimeNew', (jClass,), jObject)
@@ -658,6 +659,11 @@
jtype, jidx = self.curfunc.function_arguments[index]
self.load_jvm_var(jtype, jidx)
+ def prepare_generic_argument(self, ITEMTYPE):
+ jty = self.db.lltype_to_cts(ITEMTYPE)
+ if isinstance(jty, JvmScalarType):
+ self.box_value(jty)
+
def box_value(self, jscalartype):
""" Assuming that an value of type jscalartype is on the stack,
boxes it into an Object. """
@@ -715,6 +721,7 @@
# wrapped Python object
self.mark(catch)
EXCWRAPOBJ.load(self)
+ self.emit(CHECKCAST, excclsty)
def end_catch(self):
"""
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 13:45:45 2007
@@ -223,12 +223,12 @@
else:
# the exception value is on the stack, store it in the proper place
if isinstance(link.last_exception, flowmodel.Variable):
- self.ilasm.dup(jObject)
+ self.ilasm.emit(jvmgen.DUP)
self.ilasm.store(link.last_exc_value)
fld = jvmgen.Field(
- self.db.lltype_to_cts(rclass.CLASSTYPE).name,
+ self.db.lltype_to_cts(rclass.OBJECT).name,
'meta',
- self.db.lltype_to_cts(rclass.OBJECT),
+ self.db.lltype_to_cts(rclass.CLASSTYPE),
False,
rclass.OBJECT)
self.ilasm.emit(fld)
@@ -476,7 +476,9 @@
genprint = self._print
# Start the dump
- genprint("InstanceWrapper([")
+ genprint("InstanceWrapper(")
+ genprint("'" + self.OOCLASS._name + "', ")
+ genprint("[")
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java Thu Jan 11 13:45:45 2007
@@ -221,6 +221,14 @@
sb.append(c);
}
+ public static String escaped_char(char c) {
+ StringBuffer sb = new StringBuffer();
+ sb.append('"');
+ _append_char(sb, c);
+ sb.append('"');
+ return sb.toString();
+ }
+
public static String escaped_string(String b) {
StringBuffer sb = new StringBuffer();
sb.append('"');
Modified: pypy/dist/pypy/translator/jvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/runtest.py (original)
+++ pypy/dist/pypy/translator/jvm/test/runtest.py Thu Jan 11 13:45:45 2007
@@ -48,12 +48,13 @@
return 'ExceptionWrapper(%s)' % repr(self.class_name)
class InstanceWrapper:
- def __init__(self, fields):
+ def __init__(self, class_name, fields):
+ self.class_name = class_name
# fields is a list of (name, value) tuples
self.fields = fields
def __repr__(self):
- return 'InstanceWrapper(%s)' % repr(self.fields)
+ return 'InstanceWrapper(%s, %r)' % (self.class_name, self.fields)
# CLI could-be duplicate
class JvmGeneratedSourceWrapper(object):
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Thu Jan 11 13:45:45 2007
@@ -146,7 +146,9 @@
jIntegerClass = JvmClassType('java.lang.Integer')
jLongClass = JvmClassType('java.lang.Long')
jDoubleClass = JvmClassType('java.lang.Double')
-jCharClass = JvmClassType('java.lang.Char')
+jByteClass = JvmClassType('java.lang.Byte')
+jCharClass = JvmClassType('java.lang.Character')
+jBoolClass = JvmClassType('java.lang.Boolean')
jThrowable = JvmClassType('java.lang.Throwable')
jObject = JvmClassType('java.lang.Object')
jString = JvmClassType('java.lang.String')
@@ -179,10 +181,10 @@
jVoid = JvmScalarType('V', None, None)
jInt = JvmScalarType('I', jIntegerClass, 'intValue')
jLong = JvmScalarType('J', jLongClass, 'longValue')
-jBool = JvmScalarType('Z', jIntegerClass, 'intValue')
+jBool = JvmScalarType('Z', jBoolClass, 'booleanValue')
jDouble = JvmScalarType('D', jDoubleClass, 'doubleValue')
-jByte = JvmScalarType('B', jIntegerClass, 'intValue')
-jChar = JvmScalarType('C', jIntegerClass, 'intValue')
+jByte = JvmScalarType('B', jByteClass, 'byteValue')
+jChar = JvmScalarType('C', jCharClass, 'charValue')
class JvmArrayType(JvmType):
"""
Modified: pypy/dist/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/constant.py (original)
+++ pypy/dist/pypy/translator/oosupport/constant.py Thu Jan 11 13:45:45 2007
@@ -590,6 +590,7 @@
gen.dup(SELFTYPE)
push_constant(self.db, ootype.Signed, idx, gen)
push_constant(self.db, ITEMTYPE, item, gen)
+ gen.prepare_generic_argument(ITEMTYPE)
gen.call_method(SELFTYPE, 'll_setitem_fast')
# ______________________________________________________________________
Modified: pypy/dist/pypy/translator/oosupport/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/metavm.py (original)
+++ pypy/dist/pypy/translator/oosupport/metavm.py Thu Jan 11 13:45:45 2007
@@ -156,6 +156,14 @@
Stack: argN...arg2, arg1, arg0, ... -> ret, ... """
raise NotImplementedError
+ def prepare_generic_argument(self, ITEMTYPE):
+ """
+ Invoked after a generic argument has been pushed onto the stack.
+ May not need to do anything, but some backends, *cough*Java*cough*,
+ require boxing etc.
+ """
+ return # by default do nothing
+
def call_method(self, OOCLASS, method_name):
""" Invokes the given method on the object on the stack. The
this ptr and all arguments have already been pushed.
From pedronis at codespeak.net Thu Jan 11 13:53:49 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Thu, 11 Jan 2007 13:53:49 +0100 (CET)
Subject: [pypy-svn] r36475 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070111125349.7F27410082@code0.codespeak.net>
Author: pedronis
Date: Thu Jan 11 13:53:46 2007
New Revision: 36475
Modified:
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/oop.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
pypy/dist/pypy/jit/timeshifter/vdict.py
pypy/dist/pypy/jit/timeshifter/vlist.py
Log:
(arre, pedronis)
- make escaping of virtualizable (getgenvar) schedule them for store_back with test
- more tests that already work about structure pointers inside a virtualizable struct
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Thu Jan 11 13:53:46 2007
@@ -125,8 +125,8 @@
if not ll_etype:
return # we known there is no exception set
evaluebox = jitstate.exc_value_box
- gv_etype = etypebox .getgenvar(builder)
- gv_evalue = evaluebox.getgenvar(builder)
+ gv_etype = etypebox .getgenvar(jitstate)
+ gv_evalue = evaluebox.getgenvar(jitstate)
builder.genop_call(tok_raise,
gv_rpyexc_raise, [gv_etype, gv_evalue])
self.store_global_excdata = store_global_excdata
@@ -140,13 +140,13 @@
def ll_finish_jitstate(jitstate, graphsigtoken):
assert jitstate.resuming is None
returnbox = rtimeshift.getreturnbox(jitstate)
- gv_ret = returnbox.getgenvar(jitstate.curbuilder)
+ gv_ret = returnbox.getgenvar(jitstate)
builder = jitstate.curbuilder
for virtualizable_box in jitstate.virtualizables:
assert isinstance(virtualizable_box, rvalue.PtrRedBox)
content = virtualizable_box.content
assert isinstance(content, rcontainer.VirtualizableStruct)
- content.store_back(builder)
+ content.store_back(jitstate)
store_global_excdata(jitstate)
jitstate.curbuilder.finish_and_return(graphsigtoken, gv_ret)
self.ll_finish_jitstate = ll_finish_jitstate
@@ -354,7 +354,7 @@
key = key + (x,)
else:
box = args[i]
- args_gv.append(box.getgenvar(curbuilder))
+ args_gv.append(box.getgenvar(jitstate))
i = i + 1
sigtoken = rgenop.sigToken(FUNC)
cache = state.cache
Modified: pypy/dist/pypy/jit/timeshifter/oop.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/oop.py (original)
+++ pypy/dist/pypy/jit/timeshifter/oop.py Thu Jan 11 13:53:46 2007
@@ -118,7 +118,7 @@
args_gv = []
fold = deepfrozen
for argsrc in self.residualargsources:
- gv_arg = argboxes[argsrc].getgenvar(builder)
+ gv_arg = argboxes[argsrc].getgenvar(jitstate)
args_gv.append(gv_arg)
fold &= gv_arg.is_const
if fold:
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Thu Jan 11 13:53:46 2007
@@ -85,8 +85,9 @@
self.null = self.PTRTYPE._defl()
self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
- if TYPE._hints.get('virtualizable', False):
- self.__class__ = VirtualizableStructTypeDesc
+
+ self.virtualizable = TYPE._hints.get('virtualizable', False)
+ if self.virtualizable:
self.VStructCls = VirtualizableStruct
else:
self.VStructCls = VirtualStruct
@@ -108,9 +109,13 @@
return self.fielddesc_by_name[name]
def factory(self):
- vstruct = VirtualStruct(self)
+ vstruct = self.VStructCls(self)
vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
for desc in self.fielddescs]
+ if self.virtualizable:
+ outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind,
+ self.gv_null)
+ vstruct.content_boxes.append(outsidebox)
box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
box.content = vstruct
vstruct.ownbox = box
@@ -125,20 +130,6 @@
def compact_repr(self): # goes in ll helper names
return "Desc_%s" % (self.TYPE._short_name(),)
-
-class VirtualizableStructTypeDesc(StructTypeDesc):
-
- def factory(self):
- vstruct = VirtualizableStruct(self)
- vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
- for desc in self.fielddescs]
- outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind,
- self.gv_null)
- vstruct.content_boxes.append(outsidebox)
- box = rvalue.PtrRedBox(self.innermostdesc.ptrkind)
- box.content = vstruct
- vstruct.ownbox = box
- return box
# XXX basic field descs for now
class FieldDesc(object):
@@ -176,8 +167,8 @@
gv_item = builder.genop_getfield(self.fieldtoken, genvar)
return self.redboxcls(self.kind, gv_item)
- def generate_set(self, builder, genvar, box):
- builder.genop_setfield(self.fieldtoken, genvar, box.getgenvar(builder))
+ def generate_set(self, builder, genvar, gv_value):
+ builder.genop_setfield(self.fieldtoken, genvar, gv_value)
def generate_getsubstruct(self, builder, genvar):
gv_sub = builder.genop_getsubstruct(self.fieldtoken, genvar)
@@ -271,9 +262,10 @@
for box in self.content_boxes:
box.enter_block(incoming, memo)
- def force_runtime_container(self, builder):
+ def force_runtime_container(self, jitstate):
typedesc = self.typedesc
assert typedesc is not None
+ builder = jitstate.curbuilder
boxes = self.content_boxes
self.content_boxes = None
if typedesc.materialize is not None:
@@ -295,7 +287,7 @@
for i in range(len(fielddescs)):
fielddesc = fielddescs[i]
box = boxes[i]
- fielddesc.generate_set(builder, genvar, box)
+ fielddesc.generate_set(builder, genvar, box.getgenvar(jitstate))
def freeze(self, memo):
contmemo = memo.containers
@@ -338,27 +330,29 @@
class VirtualizableStruct(VirtualStruct):
- def force_runtime_container(self, builder):
+ def force_runtime_container(self, jitstate):
assert 0
- def getgenvar(self, builder):
+ def getgenvar(self, jitstate):
typedesc = self.typedesc
assert typedesc is not None
+ builder = jitstate.curbuilder
gv_outside = self.content_boxes[-1].genvar
if gv_outside is typedesc.gv_null:
gv_outside = builder.genop_malloc_fixedsize(typedesc.alloctoken)
self.content_boxes[-1].genvar = gv_outside
- # xxx jitstate please
+ jitstate.add_virtualizable(self.ownbox)
return gv_outside
- def store_back(self, builder):
+ def store_back(self, jitstate):
fielddescs = self.typedesc.fielddescs
boxes = self.content_boxes
gv_outside = boxes[-1].genvar
for i in range(1, len(fielddescs)):
fielddesc = fielddescs[i]
box = boxes[i]
- fielddesc.generate_set(builder, gv_outside, box)
+ fielddesc.generate_set(jitstate.curbuilder, gv_outside,
+ box.getgenvar(jitstate))
# ____________________________________________________________
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Thu Jan 11 13:53:46 2007
@@ -74,7 +74,7 @@
arg = rvalue.ll_getvalue(argbox, ARG0)
res = opdesc.llop(RESULT, arg)
return rvalue.ll_fromvalue(jitstate, res)
- gv_arg = argbox.getgenvar(jitstate.curbuilder)
+ gv_arg = argbox.getgenvar(jitstate)
genvar = jitstate.curbuilder.genop1(opdesc.opname, gv_arg)
return opdesc.redboxcls(opdesc.result_kind, genvar)
@@ -89,13 +89,13 @@
arg1 = rvalue.ll_getvalue(argbox1, ARG1)
res = opdesc.llop(RESULT, arg0, arg1)
return rvalue.ll_fromvalue(jitstate, res)
- gv_arg0 = argbox0.getgenvar(jitstate.curbuilder)
- gv_arg1 = argbox1.getgenvar(jitstate.curbuilder)
+ gv_arg0 = argbox0.getgenvar(jitstate)
+ gv_arg1 = argbox1.getgenvar(jitstate)
genvar = jitstate.curbuilder.genop2(opdesc.opname, gv_arg0, gv_arg1)
return opdesc.redboxcls(opdesc.result_kind, genvar)
def ll_genmalloc_varsize(jitstate, contdesc, sizebox):
- gv_size = sizebox.getgenvar(jitstate.curbuilder)
+ gv_size = sizebox.getgenvar(jitstate)
alloctoken = contdesc.varsizealloctoken
genvar = jitstate.curbuilder.genop_malloc_varsize(alloctoken, gv_size)
return rvalue.PtrRedBox(contdesc.ptrkind, genvar)
@@ -125,8 +125,8 @@
return rvalue.ll_fromvalue(jitstate, res)
genvar = jitstate.curbuilder.genop_getarrayitem(
fielddesc.arraytoken,
- argbox.getgenvar(jitstate.curbuilder),
- indexbox.getgenvar(jitstate.curbuilder))
+ argbox.getgenvar(jitstate),
+ indexbox.getgenvar(jitstate))
return fielddesc.redboxcls(fielddesc.kind, genvar)
@@ -137,8 +137,8 @@
return rvalue.ll_fromvalue(jitstate, res)
genvar = jitstate.curbuilder.genop_getarraysubstruct(
fielddesc.arraytoken,
- argbox.getgenvar(jitstate.curbuilder),
- indexbox.getgenvar(jitstate.curbuilder))
+ argbox.getgenvar(jitstate),
+ indexbox.getgenvar(jitstate))
return fielddesc.redboxcls(fielddesc.kind, genvar)
@@ -146,9 +146,9 @@
def ll_gensetarrayitem(jitstate, fielddesc, destbox, indexbox, valuebox):
genvar = jitstate.curbuilder.genop_setarrayitem(
fielddesc.arraytoken,
- destbox.getgenvar(jitstate.curbuilder),
- indexbox.getgenvar(jitstate.curbuilder),
- valuebox.getgenvar(jitstate.curbuilder)
+ destbox.getgenvar(jitstate),
+ indexbox.getgenvar(jitstate),
+ valuebox.getgenvar(jitstate)
)
return fielddesc.redboxcls(fielddesc.kind, genvar)
@@ -160,7 +160,7 @@
return rvalue.ll_fromvalue(jitstate, res)
genvar = jitstate.curbuilder.genop_getarraysize(
fielddesc.arraytoken,
- argbox.getgenvar(jitstate.curbuilder))
+ argbox.getgenvar(jitstate))
return rvalue.IntRedBox(fielddesc.indexkind, genvar)
def ll_genptrnonzero(jitstate, argbox, reverse):
@@ -169,7 +169,7 @@
return rvalue.ll_fromvalue(jitstate, bool(addr) ^ reverse)
builder = jitstate.curbuilder
if argbox.content is None:
- gv_addr = argbox.getgenvar(builder)
+ gv_addr = argbox.getgenvar(jitstate)
if reverse:
gv_res = builder.genop1("ptr_iszero", gv_addr)
else:
@@ -187,8 +187,8 @@
addr0 = rvalue.ll_getvalue(argbox0, llmemory.Address)
addr1 = rvalue.ll_getvalue(argbox1, llmemory.Address)
return rvalue.ll_fromvalue(jitstate, (addr0 == addr1) ^ reverse)
- gv_addr0 = argbox0.getgenvar(builder)
- gv_addr1 = argbox1.getgenvar(builder)
+ gv_addr0 = argbox0.getgenvar(jitstate)
+ gv_addr1 = argbox1.getgenvar(jitstate)
if reverse:
gv_res = builder.genop2("ptr_ne", gv_addr0, gv_addr1)
else:
@@ -260,7 +260,7 @@
if match:
linkargs = []
for box in outgoingvarboxes:
- linkargs.append(box.getgenvar(jitstate.curbuilder))
+ linkargs.append(box.getgenvar(jitstate))
jitstate.curbuilder.finish_and_goto(linkargs, oldblock)
return True # finished
# A mergable blook found
@@ -270,7 +270,7 @@
cleanup_partial_data(memo.partialdatamatch)
replace_memo = rvalue.copy_memo()
for box in outgoingvarboxes:
- box.forcevar(jitstate.curbuilder, replace_memo)
+ box.forcevar(jitstate, replace_memo)
if replace_memo.boxes:
jitstate.replace(replace_memo)
start_new_block(states_dic, jitstate, key, global_resumer, index=i)
@@ -317,7 +317,7 @@
jitstate.resumepoint = resumepoint
def split(jitstate, switchredbox, resumepoint, *greens_gv):
- exitgvar = switchredbox.getgenvar(jitstate.curbuilder)
+ exitgvar = switchredbox.getgenvar(jitstate)
if exitgvar.is_const:
return exitgvar.revealconst(lltype.Bool)
else:
@@ -446,7 +446,7 @@
dispatchqueue.return_chain = jitstate
##def ll_gvar_from_redbox(jitstate, redbox):
-## return redbox.getgenvar(jitstate.curbuilder)
+## return redbox.getgenvar(jitstate)
##def ll_gvar_from_constant(jitstate, ll_value):
## return jitstate.curbuilder.rgenop.genconst(ll_value)
@@ -464,9 +464,9 @@
def ll_gen_residual_call(jitstate, calldesc, funcbox):
builder = jitstate.curbuilder
- gv_funcbox = funcbox.getgenvar(builder)
+ gv_funcbox = funcbox.getgenvar(jitstate)
argboxes = jitstate.frame.local_boxes
- args_gv = [argbox.getgenvar(builder) for argbox in argboxes]
+ args_gv = [argbox.getgenvar(jitstate) for argbox in argboxes]
gv_result = builder.genop_call(calldesc.sigtoken, gv_funcbox, args_gv)
return calldesc.redboxbuilder(calldesc.result_kind, gv_result)
@@ -621,7 +621,7 @@
def ll_promote(jitstate, promotebox, promotiondesc):
builder = jitstate.curbuilder
- gv_switchvar = promotebox.getgenvar(builder)
+ gv_switchvar = promotebox.getgenvar(jitstate)
if gv_switchvar.is_const:
return False
else:
@@ -645,7 +645,7 @@
[gv_pm, gv_switchvar])
linkargs = []
for box in incoming:
- linkargs.append(box.getgenvar(default_builder))
+ linkargs.append(box.getgenvar(jitstate))
default_builder.finish_and_goto(linkargs, switchblock)
return True
else:
@@ -774,6 +774,7 @@
for fz_virtualizable_box in self.fz_virtualizables:
virtualizable_box = fz_virtualizable_box.unfreeze(incomingvarboxes,
memo)
+ assert isinstance(virtualizable_box, rvalue.PtrRedBox)
virtualizables[virtualizable_box] = None
return JITState(None, frame, exc_type_box, exc_value_box,
virtualizables=virtualizables)
@@ -837,13 +838,16 @@
self.virtualizables = virtualizables
def add_virtualizable(self, virtualizable_box):
+ assert isinstance(virtualizable_box, rvalue.PtrRedBox)
self.virtualizables[virtualizable_box] = None
def split(self, newbuilder, newresumepoint, newgreens):
memo = rvalue.copy_memo()
virtualizables = {}
for virtualizable_box in self.virtualizables:
- virtualizables[virtualizable_box.copy(memo)] = None
+ new_virtualizable_box = virtualizable_box.copy(memo)
+ assert isinstance(new_virtualizable_box, rvalue.PtrRedBox)
+ virtualizables[new_virtualizable_box] = None
later_jitstate = JITState(newbuilder,
self.frame.copy(memo),
self.exc_type_box .copy(memo),
@@ -872,10 +876,9 @@
for virtualizable_box in virtualizables.keys():
if virtualizable_box.content not in memo.containers:
del virtualizables[virtualizable_box]
- assert isinstance(virtualizable_box, rvalue.PtrRedBox)
content = virtualizable_box.content
assert isinstance(content, rcontainer.VirtualizableStruct)
- content.store_back(builder)
+ content.store_back(self)
return incoming
def freeze(self, memo):
@@ -895,7 +898,9 @@
self.exc_value_box = self.exc_value_box.replace(memo)
virtualizables = {}
for virtualizable_box in self.virtualizables:
- virtualizables[virtualizable_box.replace(memo)] = None
+ new_virtualizable_box = virtualizable_box.replace(memo)
+ assert isinstance(new_virtualizable_box, rvalue.PtrRedBox)
+ virtualizables[new_virtualizable_box] = None
self.virtualizables = virtualizables
def get_locals_gv(self): # xxx
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Thu Jan 11 13:53:46 2007
@@ -44,7 +44,7 @@
def is_constant(self):
return bool(self.genvar) and self.genvar.is_const
- def getgenvar(self, builder):
+ def getgenvar(self, jitstate):
return self.genvar
def enter_block(self, incoming, memo):
@@ -53,7 +53,8 @@
incoming.append(self)
memo[self] = None
- def forcevar(self, builder, memo):
+ def forcevar(self, jitstate, memo):
+ builder = jitstate.curbuilder
if self.is_constant():
# cannot mutate constant boxes in-place
box = self.copy(memo)
@@ -61,7 +62,7 @@
return box
else:
# force virtual containers
- self.getgenvar(builder)
+ self.getgenvar(jitstate)
return self
def replace(self, memo):
@@ -188,7 +189,7 @@
box = self.content.op_getfield(jitstate, fielddesc)
if box is not None:
return box
- gv_ptr = self.getgenvar(jitstate.curbuilder)
+ gv_ptr = self.getgenvar(jitstate)
box = fielddesc.generate_get(jitstate.curbuilder, gv_ptr)
if fielddesc.immutable:
self.remember_field(fielddesc, box)
@@ -197,7 +198,8 @@
def op_setfield(self, jitstate, fielddesc, valuebox):
gv_ptr = self.genvar
if gv_ptr:
- fielddesc.generate_set(jitstate.curbuilder, gv_ptr, valuebox)
+ fielddesc.generate_set(jitstate.curbuilder, gv_ptr,
+ valuebox.getgenvar(jitstate))
else:
assert self.content is not None
self.content.op_setfield(jitstate, fielddesc, valuebox)
@@ -270,22 +272,22 @@
boxmemo[self] = result
return result
- def getgenvar(self, builder):
+ def getgenvar(self, jitstate):
if not self.genvar:
content = self.content
from pypy.jit.timeshifter import rcontainer
if isinstance(content, rcontainer.VirtualizableStruct):
- return content.getgenvar(builder)
+ return content.getgenvar(jitstate)
assert isinstance(content, rcontainer.VirtualContainer)
- content.force_runtime_container(builder)
+ content.force_runtime_container(jitstate)
assert self.genvar
return self.genvar
- def forcevar(self, builder, memo):
+ def forcevar(self, jitstate, memo):
from pypy.jit.timeshifter import rcontainer
# xxx
assert not isinstance(self.content, rcontainer.VirtualizableStruct)
- return RedBox.forcevar(self, builder, memo)
+ return RedBox.forcevar(self, jitstate, memo)
def enter_block(self, incoming, memo):
if self.genvar:
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Thu Jan 11 13:53:46 2007
@@ -3,15 +3,35 @@
import py
+S = lltype.GcStruct('s', ('a', lltype.Signed), ('b', lltype.Signed))
+PS = lltype.Ptr(S)
+
XY = lltype.GcForwardReference()
-GETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY)], lltype.Signed))
-SETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XY), lltype.Signed],
- lltype.Void))
-XY_ACCESS = lltype.Struct('xy',
- ('get_x', GETTER),
- ('set_x', SETTER),
- ('get_y', GETTER),
- ('set_y', SETTER),
+GETTER = lambda STRUC: lltype.Ptr(lltype.FuncType([lltype.Ptr(STRUC)],
+ lltype.Signed))
+SETTER = lambda STRUC: lltype.Ptr(lltype.FuncType([lltype.Ptr(STRUC),
+ lltype.Signed],
+ lltype.Void))
+
+XP = lltype.GcForwardReference()
+PGETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XP)], PS))
+PSETTER = lltype.Ptr(lltype.FuncType([lltype.Ptr(XP), PS],
+ lltype.Void))
+
+XY_ACCESS = lltype.Struct('xy_access',
+ ('get_x', GETTER(XY)),
+ ('set_x', SETTER(XY)),
+ ('get_y', GETTER(XY)),
+ ('set_y', SETTER(XY)),
+ hints = {'immutable': True},
+ )
+
+
+XP_ACCESS = lltype.Struct('xp_access',
+ ('get_x', GETTER(XP)),
+ ('set_x', SETTER(XP)),
+ ('get_p', PGETTER),
+ ('set_p', PSETTER),
hints = {'immutable': True},
)
@@ -21,6 +41,14 @@
('y', lltype.Signed),
hints = {'virtualizable': True}
))
+
+XP.become(lltype.GcStruct('xp',
+ ('access', lltype.Ptr(XP_ACCESS)),
+ ('x', lltype.Signed),
+ ('p', PS),
+ hints = {'virtualizable': True}
+ ))
+
class TestVirtualizable(PortalTest):
@@ -216,7 +244,6 @@
self.check_insns(getfield=0)
def test_simple_explicit_construct_escape(self):
- py.test.skip("in-progress")
def f(x, y):
xy = lltype.malloc(XY)
@@ -242,3 +269,139 @@
res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
assert res == 42
self.check_insns(getfield=0)
+
+ def test_simple_with_struct_explicit(self):
+
+ def f(xp):
+ xp_access = xp.access
+ if xp_access:
+ x = xp_access.get_x(xp)
+ else:
+ x = xp.x
+ xp_access = xp.access
+ if xp_access:
+ p = xp_access.get_p(xp)
+ else:
+ p = xp.p
+ return x+p.a+p.b
+
+ def main(x, a, b):
+ xp = lltype.malloc(XP)
+ xp.access = lltype.nullptr(XP_ACCESS)
+ xp.x = x
+ s = lltype.malloc(S)
+ s.a = a
+ s.b = b
+ xp.p = s
+ return f(xp)
+
+ res = self.timeshift_from_portal(main, f, [20, 10, 12],
+ policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=2)
+
+ def test_simple_with_setting_struct_explicit(self):
+
+ def f(xp, s):
+ xp_access = xp.access
+ if xp_access:
+ xp_access.set_p(xp, s)
+ else:
+ xp.p = s
+ if xp_access:
+ x = xp_access.get_x(xp)
+ else:
+ x = xp.x
+ xp_access = xp.access
+ if xp_access:
+ p = xp_access.get_p(xp)
+ else:
+ p = xp.p
+ p.b = p.b*2
+ return x+p.a+p.b
+
+ def main(x, a, b):
+ xp = lltype.malloc(XP)
+ xp.access = lltype.nullptr(XP_ACCESS)
+ xp.x = x
+ s = lltype.malloc(S)
+ s.a = a
+ s.b = b
+ v = f(xp, s)
+ return v+xp.p.b
+
+ res = self.timeshift_from_portal(main, f, [20, 10, 3],
+ policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=3)
+
+ def test_simple_with_setting_new_struct_explicit(self):
+
+ def f(xp, a, b):
+ s = lltype.malloc(S)
+ s.a = a
+ s.b = b
+ xp_access = xp.access
+ if xp_access:
+ xp_access.set_p(xp, s)
+ else:
+ xp.p = s
+ xp_access = xp.access
+ if xp_access:
+ p = xp_access.get_p(xp)
+ else:
+ p = xp.p
+ p.b = p.b*2
+ if xp_access:
+ x = xp_access.get_x(xp)
+ else:
+ x = xp.x
+ return x+p.a+p.b
+
+ def main(x, a, b):
+ xp = lltype.malloc(XP)
+ xp.access = lltype.nullptr(XP_ACCESS)
+ xp.x = x
+ v = f(xp, a, b)
+ return v+xp.p.b
+
+ res = self.timeshift_from_portal(main, f, [20, 10, 3],
+ policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=2, malloc=1)
+
+
+ def test_simple_constr_with_setting_new_struct_explicit(self):
+
+ def f(x, a, b):
+ xp = lltype.malloc(XP)
+ xp.access = lltype.nullptr(XP_ACCESS)
+ xp.x = x
+ s = lltype.malloc(S)
+ s.a = a
+ s.b = b
+ xp_access = xp.access
+ if xp_access:
+ xp_access.set_p(xp, s)
+ else:
+ xp.p = s
+ xp_access = xp.access
+ if xp_access:
+ p = xp_access.get_p(xp)
+ else:
+ p = xp.p
+ p.b = p.b*2
+ if xp_access:
+ x = xp_access.get_x(xp)
+ else:
+ x = xp.x
+ return xp
+
+ def main(x, a, b):
+ xp = f(x, a, b)
+ return xp.x+xp.p.a+xp.p.b+xp.p.b
+
+ res = self.timeshift_from_portal(main, f, [20, 10, 3],
+ policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=0, malloc=2)
Modified: pypy/dist/pypy/jit/timeshifter/vdict.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vdict.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vdict.py Thu Jan 11 13:53:46 2007
@@ -199,8 +199,9 @@
for box in self.getboxes():
box.enter_block(incoming, memo)
- def force_runtime_container(self, builder):
+ def force_runtime_container(self, jitstate):
typedesc = self.typedesc
+ builder = jitstate.curbuilder
items = self.getitems_and_makeempty(builder.rgenop)
args_gv = []
@@ -211,7 +212,7 @@
self.ownbox.content = None
for gv_key, valuebox, hash in items:
gv_hash = builder.rgenop.genconst(hash)
- gv_value = valuebox.getgenvar(builder)
+ gv_value = valuebox.getgenvar(jitstate)
args_gv = [gv_dict, gv_key, gv_value, gv_hash]
builder.genop_call(typedesc.tok_ll_insertclean,
typedesc.gv_ll_insertclean,
Modified: pypy/dist/pypy/jit/timeshifter/vlist.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/vlist.py (original)
+++ pypy/dist/pypy/jit/timeshifter/vlist.py Thu Jan 11 13:53:46 2007
@@ -107,8 +107,9 @@
for box in self.item_boxes:
box.enter_block(incoming, memo)
- def force_runtime_container(self, builder):
+ def force_runtime_container(self, jitstate):
typedesc = self.typedesc
+ builder = jitstate.curbuilder
boxes = self.item_boxes
self.item_boxes = None
@@ -119,7 +120,7 @@
self.ownbox.genvar = gv_list
self.ownbox.content = None
for i in range(len(boxes)):
- gv_item = boxes[i].getgenvar(builder)
+ gv_item = boxes[i].getgenvar(jitstate)
args_gv = [gv_list, builder.rgenop.genconst(i), gv_item]
builder.genop_call(typedesc.tok_ll_setitem_fast,
typedesc.gv_ll_setitem_fast,
From arigo at codespeak.net Thu Jan 11 14:27:19 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 11 Jan 2007 14:27:19 +0100 (CET)
Subject: [pypy-svn] r36478 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070111132719.B1BE910083@code0.codespeak.net>
Author: arigo
Date: Thu Jan 11 14:27:16 2007
New Revision: 36478
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
Log:
- spill registers on the frame stack.
- start some support for int_gt.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Thu Jan 11 14:27:16 2007
@@ -27,6 +27,7 @@
return # simple operation whose result is not used anyway
op = allocator.load_location_with(loc, self.x)
self.emit(allocator.mc, op)
+ allocator.store_back_location(loc, op)
class OpSameAs(Op1):
emit = staticmethod(lambda mc, x: None)
@@ -46,6 +47,7 @@
op1 = allocator.load_location_with(loc, self.x)
op2 = allocator.get_operand(self.y)
self.emit(allocator.mc, op1, op2)
+ allocator.store_back_location(loc, op1)
class OpIntAdd(Op2):
opname = 'int_add'
@@ -55,6 +57,29 @@
opname = 'int_sub'
emit = staticmethod(I386CodeBuilder.SUB)
+class OpIntGt(Op2):
+ opname = 'int_gt'
+ @staticmethod
+ def emit(mc, x, y):
+ mc.CMP(x, y)
+ mc.SETG(cl)
+ mc.MOVZX(x, cl)
+
+class JumpIfFalse(Operation):
+ def __init__(self, gv_condition, targetbuilder):
+ self.gv_condition = gv_condition
+ self.targetbuilder = targetbuilder
+ def allocate_registers(self, allocator):
+ allocator.using(self.gv_condition)
+ def generate(self, allocator):
+ op = allocator.get_operand(self.gv_condition)
+ mc = allocator.mc
+ mc.CMP(op, imm8(0))
+ targetbuilder = self.targetbuilder
+ targetbuilder.set_coming_from(mc, insn=I386CodeBuilder.JE)
+ targetbuilder.inputoperands = [allocator.get_operand(gv)
+ for gv in targetbuilder.inputargs_gv]
+
# ____________________________________________________________
class IntConst(GenConst):
@@ -135,12 +160,27 @@
OPCLASSES1['int_is_true'] = None
-class OutOfRegisters(Exception):
- pass
+class StackOpCache:
+ INITIAL_STACK_EBP_OFS = -4
+stack_op_cache = StackOpCache()
+stack_op_cache.lst = []
+
+def stack_op(n):
+ "Return the mem operand that designates the nth stack-spilled location"
+ assert n >= 0
+ lst = stack_op_cache.lst
+ while len(lst) <= n:
+ ofs = WORD * (StackOpCache.INITIAL_STACK_EBP_OFS - len(lst))
+ lst.append(mem(ebp, ofs))
+ return lst[n]
+
+def stack_n_from_op(op):
+ ofs = op.ofs_relative_to_ebp()
+ return StackOpCache.INITIAL_STACK_EBP_OFS - ofs / WORD
class RegAllocator(object):
- AVAILABLE_REGS = [eax, ecx, edx, ebx, esi, edi]
+ AVAILABLE_REGS = [eax, edx, ebx, esi, edi] # XXX ecx reserved for stuff
# 'gv' -- GenVars, used as arguments and results of operations
#
@@ -212,24 +252,33 @@
force_loc2operand = self.force_loc2operand
operands = []
seen_regs = 0
+ seen_stackn = {}
for op in force_loc2operand.values():
if isinstance(op, REG):
seen_regs |= 1 << op.op
+ elif isinstance(op, MODRM):
+ seen_stackn[stack_n_from_op(op)] = None
i = 0
+ stackn = 0
for loc in range(self.nextloc):
try:
operand = force_loc2operand[loc]
except KeyError:
# grab the next free register
- while seen_regs & (1 << i):
- i += 1
try:
- operand = RegAllocator.AVAILABLE_REGS[i]
- i += 1
+ while True:
+ operand = RegAllocator.AVAILABLE_REGS[i]
+ i += 1
+ if not (seen_regs & (1 << operand.op)):
+ break
except IndexError:
- raise OutOfRegisters
+ while stackn in seen_stackn:
+ stackn += 1
+ operand = stack_op(stackn)
+ stackn += 1
operands.append(operand)
self.operands = operands
+ self.required_frame_depth = stackn
def get_operand(self, gv_source):
if isinstance(gv_source, IntConst):
@@ -240,14 +289,30 @@
def load_location_with(self, loc, gv_source):
dstop = self.operands[loc]
+ if not isinstance(dstop, REG):
+ dstop = ecx
srcop = self.get_operand(gv_source)
if srcop != dstop:
self.mc.MOV(dstop, srcop)
return dstop
+ def store_back_location(self, loc, operand):
+ dstop = self.operands[loc]
+ if operand != dstop:
+ self.mc.MOV(dstop, operand)
+
def generate_initial_moves(self):
- # XXX naive algo for now
initial_moves = self.initial_moves
+ # first make sure that the reserved stack frame is big enough
+ last_n = self.required_frame_depth - 1
+ for loc, srcoperand in initial_moves:
+ if isinstance(srcoperand, MODRM):
+ n = stack_n_from_op(srcoperand)
+ if last_n < n:
+ last_n = n
+ if last_n >= 0:
+ self.mc.LEA(esp, stack_op(last_n))
+ # XXX naive algo for now
for loc, srcoperand in initial_moves:
self.mc.PUSH(srcoperand)
initial_moves.reverse()
@@ -273,7 +338,6 @@
allocator.allocate_locations(self.operations)
allocator.force_var_operands(force_vars, force_operands,
at_start=False)
- #import pdb; pdb.set_trace()
allocator.force_var_operands(self.inputargs_gv, self.inputoperands,
at_start=True)
allocator.allocate_registers()
@@ -284,33 +348,10 @@
op.generate(allocator)
self.operations = None
self.inputargs_gv = [GenVar() for v in final_vars_gv]
- self.inputoperands = [allocator.operands[allocator.var2loc[v]]
- for v in final_vars_gv]
+ self.inputoperands = [allocator.get_operand(v) for v in final_vars_gv]
return mc
def enter_next_block(self, kinds, args_gv):
-## locs = {}
-## seen_regs = 0
-## for v in args_gv:
-## loc = self.input_var2loc.get(v, None)
-## locs[v] = loc
-## if isinstance(loc, REG):
-## i = loc.op
-## seen_regs |= 1 << i
-## i = 0
-## final_locs = []
-## final_var2loc = {}
-## for v in args_gv:
-## loc = locs[v]
-## if loc is None:
-## while seen_regs & (1 << i):
-## i += 1
-## assert i < len(RegAllocator.AVAILABLE_REGS) # XXX
-## loc = RegAllocator.AVAILABLE_REGS[i]
-## i += 1
-## final_locs.append(loc)
-## final_var2loc[v] = loc
-
mc = self.generate_block_code(args_gv)
args_gv[:] = self.inputargs_gv
self.set_coming_from(mc)
@@ -336,9 +377,15 @@
self.coming_from = 0
return mc
+ def jump_if_false(self, gv_condition, args_for_jump_gv):
+ newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None)
+ self.operations.append(JumpIfFalse(gv_condition, newbuilder))
+ return newbuilder
+
def finish_and_return(self, sigtoken, gv_returnvar):
mc = self.generate_block_code([gv_returnvar], [gv_returnvar], [eax])
# --- epilogue ---
+ mc.LEA(esp, mem(ebp, -12))
mc.POP(edi)
mc.POP(esi)
mc.POP(ebx)
@@ -422,7 +469,7 @@
#ops = [OpSameAs(v) for v in inputargs_gv]
#builder.operations.extend(ops)
#inputargs_gv = ops
- return builder, IntConst(entrypoint), inputargs_gv
+ return builder, IntConst(entrypoint), inputargs_gv[:]
## def replay(self, label, kinds):
## return ReplayBuilder(self), [dummy_var] * len(kinds)
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py Thu Jan 11 14:27:16 2007
@@ -105,6 +105,23 @@
mod = self.byte & 0xC0
return mod == 0xC0
+ def ofs_relative_to_ebp(self):
+ # very custom: if self is a mem(ebp, ofs) then return ofs
+ # otherwise raise ValueError
+ mod = self.byte & 0xC0
+ rm = self.byte & 0x07
+ if mod == 0xC0:
+ raise ValueError # self is just a register
+ if self.byte == 0x05:
+ raise ValueError # self is just an [immediate]
+ if rm != 5:
+ raise ValueError # not a simple [ebp+ofs]
+ offset = self.extradata
+ if not offset:
+ return 0
+ else:
+ return unpack(offset)
+
class MODRM8(MODRM):
width = 1
From niko at codespeak.net Thu Jan 11 15:03:32 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 15:03:32 +0100 (CET)
Subject: [pypy-svn] r36479 - in pypy/dist/pypy/translator/jvm: . src
Message-ID: <20070111140332.EA8DD10070@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 15:03:32 2007
New Revision: 36479
Modified:
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/genjvm.py
pypy/dist/pypy/translator/jvm/metavm.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/src/PyPy.java
Log:
(antocuni,niko) fix a variety of errors in test_list
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Thu Jan 11 15:03:32 2007
@@ -2,7 +2,8 @@
from pypy.translator.jvm import generator as jvmgen
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.typesystem import \
- jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject
+ jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject, \
+ jBool
# ______________________________________________________________________
# Mapping of built-in OOTypes to JVM types
@@ -59,25 +60,18 @@
# Lookup the generic method by name.
GENMETH = self.OOTYPE._GENERIC_METHODS[methodnm]
- # Create an array with the Java version of each type in the
- # argument list and return type.
- jargtypes = [self._map(P) for P in GENMETH.ARGS]
+ # By default, we assume it is a static method on the PyPy
+ # object, that takes an instance of this object as the first
+ # argument. The other arguments we just convert to java versions,
+ # except for generics.
+ jargtypes = [self] + [self._map(P) for P in GENMETH.ARGS]
jrettype = self._map(GENMETH.RESULT)
- return jvmgen.Method.v(self, methodnm, jargtypes, jrettype)
+ return jvmgen.Method.s(jPyPy, methodnm, jargtypes, jrettype)
# When we lookup a method on a BuiltInClassNode, we first check
# the 'built_in_methods' table. This allows us to redirect to other
# methods if we like.
-def _ll_build_method():
- # Choose an appropriate ll_build depending on what representation
- # we are using for ootype.String:
- if True: # XXX db.using_byte_array...
- return jvmgen.Method.v(
- jStringBuilder, "toString", (),jString)
- return jvmgen.Method.s(
- jvmgen.PYPYJAVA, "ll_build", (jStringBuilder,), jOOString)
-
built_in_methods = {
# Note: String and StringBuilder are rebound in ootype, and thus
@@ -86,14 +80,11 @@
(ootype.StringBuilder.__class__, "ll_allocate"):
jvmgen.Method.v(jStringBuilder, "ensureCapacity", (jInt,), jVoid),
- (ootype.StringBuilder.__class__, "ll_append_char"):
- jvmgen.Method.s(jPyPy, "ll_append_char", (jStringBuilder, jChar), jVoid),
-
- (ootype.StringBuilder.__class__, "ll_append"):
- jvmgen.Method.s(jPyPy, "ll_append", (jStringBuilder, jString), jVoid),
-
(ootype.StringBuilder.__class__, "ll_build"):
- _ll_build_method(),
+ jvmgen.Method.v(jStringBuilder, "toString", (), jString),
+
+ (ootype.String.__class__, "ll_streq"):
+ jvmgen.Method.v(jString, "equals", (jObject,), jBool),
(ootype.List, "ll_length"):
jvmgen.Method.v(jArrayList, "size", (), jInt),
@@ -101,17 +92,4 @@
(ootype.List, "ll_getitem_fast"):
jvmgen.Method.v(jArrayList, "get", (jInt,), jObject),
- (ootype.List, "ll_setitem_fast"):
- jvmgen.Method.s(jPyPy, "ll_setitem_fast",
- (jArrayList, jInt, jObject), jVoid),
-
- (ootype.List, "_ll_resize_ge"):
- jvmgen.Method.s(jPyPy, "_ll_resize_ge", (jArrayList, jInt), jVoid),
-
- (ootype.List, "_ll_resize_le"):
- jvmgen.Method.s(jPyPy, "_ll_resize_le", (jArrayList, jInt), jVoid),
-
- (ootype.List, "_ll_resize"):
- jvmgen.Method.s(jPyPy, "_ll_resize", (jArrayList, jInt), jVoid),
-
}
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 15:03:32 2007
@@ -2,7 +2,9 @@
from pypy.objspace.flow import model as flowmodel
from pypy.translator.oosupport.metavm import Generator
from pypy.rpython.ootypesystem import ootype
+from pypy.rlib.objectmodel import CDefinedIntSymbolic
from pypy.translator.oosupport.constant import push_constant
+import pypy.translator.jvm.typesystem as jvmtype
from pypy.translator.jvm.typesystem import \
JvmType, jString, jInt, jLong, jDouble, jBool, jString, \
jPyPy, jVoid, jMath, desc_for_method, jPrintStream, jClass, jChar, \
@@ -320,7 +322,7 @@
rettypedesc = rettype.descriptor
self.descriptor = desc_for_method(argtypesdesc, rettypedesc)
def invoke(self, gen):
- gen._instr(self.opcode, self)
+ gen._instr(self.opcode, self)
def is_static(self):
return self.opcode == INVOKESTATIC
def jasmin_syntax(self):
@@ -661,9 +663,23 @@
def prepare_generic_argument(self, ITEMTYPE):
jty = self.db.lltype_to_cts(ITEMTYPE)
- if isinstance(jty, JvmScalarType):
+ if jty is jvmtype.jVoid:
+ self.emit(ACONST_NULL)
+ elif isinstance(jty, JvmScalarType):
self.box_value(jty)
+ def prepare_generic_result(self, ITEMTYPE):
+ jresty = self.db.lltype_to_cts(ITEMTYPE)
+ if jresty is jvmtype.jVoid:
+ self.emit(POP)
+ elif isinstance(jresty, JvmScalarType):
+ # Perform any un-boxing required:
+ self.downcast_jtype(jresty.box_type)
+ self.unbox_value(jresty)
+ elif jresty != jactres:
+ # Perform any casting required:
+ self.downcast(ITEMTYPE)
+
def box_value(self, jscalartype):
""" Assuming that an value of type jscalartype is on the stack,
boxes it into an Object. """
@@ -839,14 +855,15 @@
def call_oostring(self, OOTYPE):
cts_type = self.db.lltype_to_cts(OOTYPE)
- if cts_type != jByteArray:
- mthd = Method.s(jPyPy, 'oostring', [cts_type, jInt], jString)
- self.emit(mthd)
- if self.db.using_byte_array:
- self.emit(PYPYSTRING2BYTES)
- else:
- mthd = Method.s(jPyPy, 'oostring',
- [jByteArray, jInt], jByteArray)
+
+ # treat all objects the same:
+ if isinstance(cts_type, jvmtype.JvmClassType):
+ cts_type = jObject
+
+ mthd = Method.s(jPyPy, 'oostring', [cts_type, jInt], jString)
+ self.emit(mthd)
+ if self.db.using_byte_array:
+ self.emit(PYPYSTRING2BYTES)
def new(self, TYPE):
jtype = self.db.lltype_to_cts(TYPE)
@@ -883,9 +900,13 @@
def push_null(self, OOTYPE):
self.emit(ACONST_NULL)
+ DEFINED_INT_SYMBOLICS = {'MALLOC_ZERO_FILLED':1}
+
def push_primitive_constant(self, TYPE, value):
if TYPE is ootype.Void:
return
+ elif isinstance(value, CDefinedIntSymbolic):
+ self.emit(ICONST, self.DEFINED_INT_SYMBOLICS[value.expr])
elif TYPE in (ootype.Bool, ootype.Signed):
self.emit(ICONST, int(value))
elif TYPE is ootype.Unsigned:
@@ -901,7 +922,7 @@
elif TYPE is ootype.Float:
self._push_double_constant(float(value))
elif TYPE is ootype.String:
- self.load_string(str(value))
+ self.load_string(str(value._str))
def _push_long_constant(self, value):
if value == 0:
Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py (original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py Thu Jan 11 15:03:32 2007
@@ -114,9 +114,9 @@
Compiles the .java sources into .class files, ready for execution.
"""
jascmd = [getoption('jasmin'), '-d', str(self.javadir)]
- for jasfile in self.jasmin_files:
- print "Invoking jasmin on %s" % jasfile
- self._invoke(jascmd+[jasfile], False)
+
+ print "Invoking jasmin on %s" % self.jasmin_files
+ self._invoke(jascmd+list(self.jasmin_files), False)
self.compiled = True
self._compile_helper('PyPy')
Modified: pypy/dist/pypy/translator/jvm/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/metavm.py (original)
+++ pypy/dist/pypy/translator/jvm/metavm.py Thu Jan 11 15:03:32 2007
@@ -1,5 +1,7 @@
from pypy.translator.oosupport.metavm import MicroInstruction
from pypy.translator.jvm.typesystem import JvmScalarType, JvmClassType
+import pypy.translator.jvm.generator as jvmgen
+import pypy.translator.jvm.typesystem as jvmtype
class _IndirectCall(MicroInstruction):
def render(self, gen, op):
@@ -12,28 +14,20 @@
def _invoke_method(self, gen, db, jmethod, jactargs, args, jactres, res):
for arg, jmthdty in zip(args, jactargs):
- jargty = db.lltype_to_cts(arg.concretetype)
-
# Load the argument on the stack:
gen.load(arg)
# Perform any boxing required:
- if (isinstance(jargty, JvmScalarType) and
- not isinstance(jmthdty, JvmScalarType)):
- gen.box_value(jargty)
+ jargty = db.lltype_to_cts(arg.concretetype)
+ if jargty != jmthdty:
+ gen.prepare_generic_argument(arg.concretetype)
gen.emit(jmethod)
-
- jresty = db.lltype_to_cts(res.concretetype)
- if (isinstance(jresty, JvmScalarType) and
- not isinstance(jactres, JvmScalarType)):
- # Perform any un-boxing required:
- gen.downcast_jtype(jresty.box_type)
- gen.unbox_value(jresty)
- elif jresty != jactres:
- # Perform any casting required:
- gen.downcast(res.concretetype)
+ # Perform any unboxing required:
+ jresty = db.lltype_to_cts(res.concretetype)
+ if jresty != jactres:
+ gen.prepare_generic_result(res.concretetype)
def render(self, gen, op):
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 15:03:32 2007
@@ -249,15 +249,31 @@
self.ilasm.load(exc)
self.ilasm.throw()
+ def _trace(self, str):
+ jvmgen.SYSTEMERR.load(self.generator)
+ self.generator.load_string(str)
+ jvmgen.PRINTSTREAMPRINTSTR.invoke(self.generator)
+
def _render_op(self, op):
self.generator.add_comment(str(op))
if getoption('trace'):
+ self._trace(str(op)+"\n")
+
+ OOFunction._render_op(self, op)
+
+ if (getoption('trace')
+ and op.result
+ and op.result.concretetype is not ootype.Void):
+ self._trace(" Result: ")
+ res = op.result
+ jmethod = self.db.generate_toString_method_for_ootype(
+ res.concretetype)
jvmgen.SYSTEMERR.load(self.generator)
- self.generator.load_string(str(op) + "\n")
+ self.generator.load(res)
+ self.generator.emit(jmethod)
jvmgen.PRINTSTREAMPRINTSTR.invoke(self.generator)
-
- OOFunction._render_op(self, op)
+ self._trace("\n")
class StaticMethodInterface(Node, JvmClassType):
"""
Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java Thu Jan 11 15:03:32 2007
@@ -253,6 +253,13 @@
}
// ----------------------------------------------------------------------
+ // String
+
+ public static String ll_strconcat(String str1, String str2) {
+ return str1 + str2;
+ }
+
+ // ----------------------------------------------------------------------
// StringBuffer
public static void ll_append_char(StringBuilder sb, char c) {
@@ -326,7 +333,11 @@
public static String oostring(Object obj, int base_)
{
- return String.format("<%s object>", new Object[] { obj.getClass().getName() });
+ String clnm = obj.getClass().getName();
+ int underscore = clnm.lastIndexOf('_');
+ // strip "pypy." from the start, and _NN from the end
+ clnm = clnm.substring(5, underscore);
+ return String.format("<%s object>", new Object[] { clnm });
}
public static String oostring(char ch, int base_)
From niko at codespeak.net Thu Jan 11 15:04:38 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 15:04:38 +0100 (CET)
Subject: [pypy-svn] r36480 - pypy/dist/pypy/translator/jvm
Message-ID: <20070111140438.AC78C10071@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 15:04:38 2007
New Revision: 36480
Modified:
pypy/dist/pypy/translator/jvm/generator.py
Log:
(antocuni,niko) test_list runs...
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 15:04:38 2007
@@ -676,7 +676,7 @@
# Perform any un-boxing required:
self.downcast_jtype(jresty.box_type)
self.unbox_value(jresty)
- elif jresty != jactres:
+ else:
# Perform any casting required:
self.downcast(ITEMTYPE)
From niko at codespeak.net Thu Jan 11 15:08:13 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 15:08:13 +0100 (CET)
Subject: [pypy-svn] r36484 - pypy/dist/pypy/translator/jvm/src
Message-ID: <20070111140813.9E7CC10079@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 15:08:13 2007
New Revision: 36484
Modified:
pypy/dist/pypy/translator/jvm/src/PyPy.java
Log:
(antocuni,niko) small fix for test_bool; restore lost method
Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java Thu Jan 11 15:08:13 2007
@@ -262,6 +262,12 @@
// ----------------------------------------------------------------------
// StringBuffer
+ public static void ll_append_char(StringBuilder sb, byte c) {
+ // annoyingly, the actual return code is StringBuilder, so I have
+ // to make this wrapper to ignore the return value
+ sb.append((char)c);
+ }
+
public static void ll_append_char(StringBuilder sb, char c) {
// annoyingly, the actual return code is StringBuilder, so I have
// to make this wrapper to ignore the return value
From cfbolz at codespeak.net Thu Jan 11 15:09:04 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu, 11 Jan 2007 15:09:04 +0100 (CET)
Subject: [pypy-svn] r36485 - pypy/dist/pypy/objspace/std
Message-ID: <20070111140904.7553C10074@code0.codespeak.net>
Author: cfbolz
Date: Thu Jan 11 15:09:04 2007
New Revision: 36485
Modified:
pypy/dist/pypy/objspace/std/model.py
Log:
(mwh, cfbolz) as a safety measure, remove the normal dict classes from
typeorder when using multidict.
Modified: pypy/dist/pypy/objspace/std/model.py
==============================================================================
--- pypy/dist/pypy/objspace/std/model.py (original)
+++ pypy/dist/pypy/objspace/std/model.py Thu Jan 11 15:09:04 2007
@@ -122,7 +122,8 @@
else:
imported_but_not_registered[implcls] = True
- if config.objspace.std.withstrdict:
+ if (config.objspace.std.withstrdict or
+ config.objspace.std.withmultidict):
del self.typeorder[dictobject.W_DictObject]
del self.typeorder[dictobject.W_DictIterObject]
From pedronis at codespeak.net Thu Jan 11 15:13:00 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Thu, 11 Jan 2007 15:13:00 +0100 (CET)
Subject: [pypy-svn] r36486 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070111141300.BC02610074@code0.codespeak.net>
Author: pedronis
Date: Thu Jan 11 15:12:59 2007
New Revision: 36486
Modified:
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
intermediate checkin: new test in progress
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Thu Jan 11 15:12:59 2007
@@ -110,7 +110,7 @@
def factory(self):
vstruct = self.VStructCls(self)
- vstruct.content_boxes = [desc.redboxcls(desc.kind, desc.gv_default)
+ vstruct.content_boxes = [desc.makedefaultbox()
for desc in self.fielddescs]
if self.virtualizable:
outsidebox = rvalue.PtrRedBox(self.innermostdesc.ptrkind,
@@ -143,6 +143,7 @@
self.RESTYPE = RESTYPE
self.ptrkind = RGenOp.kindToken(PTRTYPE)
self.kind = RGenOp.kindToken(RESTYPE)
+ self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
if RESTYPE is lltype.Void and self.allow_void:
pass # no redboxcls at all
else:
@@ -152,6 +153,12 @@
def _freeze_(self):
return True
+ def makedefaultbox(self):
+ return self.redboxcls(self.kind, self.gv_default)
+
+ def makebox(self, gvar):
+ return self.redboxcls(self.kind, gvar)
+
class NamedFieldDesc(FieldDesc):
def __init__(self, RGenOp, PTRTYPE, name):
@@ -165,22 +172,20 @@
def generate_get(self, builder, genvar):
gv_item = builder.genop_getfield(self.fieldtoken, genvar)
- return self.redboxcls(self.kind, gv_item)
+ return self.makebox(gv_item)
def generate_set(self, builder, genvar, gv_value):
builder.genop_setfield(self.fieldtoken, genvar, gv_value)
def generate_getsubstruct(self, builder, genvar):
gv_sub = builder.genop_getsubstruct(self.fieldtoken, genvar)
- return self.redboxcls(self.kind, gv_sub)
+ return self.makebox(gv_sub)
class StructFieldDesc(NamedFieldDesc):
def __init__(self, RGenOp, PTRTYPE, name, index):
NamedFieldDesc.__init__(self, RGenOp, PTRTYPE, name)
self.fieldindex = index
- self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
- self.defaultbox = self.redboxcls(self.kind, self.gv_default)
class ArrayFieldDesc(FieldDesc):
allow_void = True
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Thu Jan 11 15:12:59 2007
@@ -108,7 +108,7 @@
return argbox.op_getfield(jitstate, fielddesc)
def ll_gensetfield(jitstate, fielddesc, destbox, valuebox):
- return destbox.op_setfield(jitstate, fielddesc, valuebox)
+ destbox.op_setfield(jitstate, fielddesc, valuebox)
def ll_gengetsubstruct(jitstate, fielddesc, argbox):
if argbox.is_constant():
@@ -128,7 +128,7 @@
argbox.getgenvar(jitstate),
indexbox.getgenvar(jitstate))
- return fielddesc.redboxcls(fielddesc.kind, genvar)
+ return fielddesc.makebox(genvar)
def ll_gengetarraysubstruct(jitstate, fielddesc, argbox, indexbox):
if argbox.is_constant() and indexbox.is_constant():
@@ -140,7 +140,7 @@
argbox.getgenvar(jitstate),
indexbox.getgenvar(jitstate))
- return fielddesc.redboxcls(fielddesc.kind, genvar)
+ return fielddesc.makebox(genvar)
def ll_gensetarrayitem(jitstate, fielddesc, destbox, indexbox, valuebox):
@@ -150,8 +150,6 @@
indexbox.getgenvar(jitstate),
valuebox.getgenvar(jitstate)
)
-
- return fielddesc.redboxcls(fielddesc.kind, genvar)
def ll_gengetarraysize(jitstate, fielddesc, argbox):
if argbox.is_constant():
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Thu Jan 11 15:12:59 2007
@@ -42,6 +42,8 @@
hints = {'virtualizable': True}
))
+E = lltype.GcStruct('e', ('xy', lltype.Ptr(XY)))
+
XP.become(lltype.GcStruct('xp',
('access', lltype.Ptr(XP_ACCESS)),
('x', lltype.Signed),
@@ -154,7 +156,6 @@
[lltype.Ptr(XY), lltype.Signed, lltype.Signed])
def test_simple_explicit_escape(self):
- E = lltype.GcStruct('e', ('xy', lltype.Ptr(XY)))
def f(e, xy):
xy_access = xy.access
@@ -405,3 +406,29 @@
policy=P_NOVIRTUAL)
assert res == 42
self.check_insns(getfield=0, malloc=2)
+
+ def test_simple_explicit_read(self):
+ py.test.skip("WIP")
+
+ def f(e):
+ xy = e.xy
+ xy_access = xy.access
+ if xy_access:
+ xy_access.set_y(xy, 3)
+ else:
+ xy.y = 3
+ return xy.x*2
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ e = lltype.malloc(E)
+ e.xy = xy
+ v = f(e)
+ return v + e.xy.x+e.xy.y
+
+ res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
+ assert res == 63
+ self.check_insns(getfield=3)
From fijal at codespeak.net Thu Jan 11 15:39:26 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 15:39:26 +0100 (CET)
Subject: [pypy-svn] r36487 - pypy/dist/pypy/annotation/test
Message-ID: <20070111143926.5F1C11007E@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 15:39:24 2007
New Revision: 36487
Modified:
pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
Added (skipped) tests for function with known signature
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Thu Jan 11 15:39:24 2007
@@ -2450,6 +2450,36 @@
s = a.build_types(fun, [])
assert s.const == 0
+ def test_some_generic_function_call(self):
+ py.test.skip("Not implemented")
+ def g(a, b, c):
+ pass
+ g.known_signature = FunctionSignature(args=(3, 3, 3), retval=3)
+
+ def fun():
+ return g(1, 2, 3)
+ a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
+ s = a.build_types(fun, [])
+ assert isinstance(s.returntype, annmodel.SomeInteger)
+ assert not hasattr(s.returntype, 'const')
+ # assert that a know the g
+
+ def test_some_genereic_function_callback(self):
+ py.test.skip("Not implemented")
+ def g(a):
+ pass
+ g.known_signature = FunctionSignature(args=
+ [FunctionSignature(args=[1])], retval=3)
+
+ def fun2(x):
+ return x
+
+ def fun():
+ return g(fun2)
+
+ a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
+ s = a.build_types(func, [])
+ # assert that annotator knows about fun2 and is flown well
def g(n):
return [0,1,2,n]
From niko at codespeak.net Thu Jan 11 15:42:19 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 15:42:19 +0100 (CET)
Subject: [pypy-svn] r36488 - in pypy/dist/pypy/translator/jvm: . src
Message-ID: <20070111144219.7D33810070@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 15:42:18 2007
New Revision: 36488
Modified:
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/src/PyPy.java
Log:
(antocuni,niko) fix remaining errors in test_pbc (we hope)
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Thu Jan 11 15:42:18 2007
@@ -33,6 +33,12 @@
if hasattr(self.OOTYPE, param):
self.generics[getattr(self.OOTYPE, param)] = ootype.ROOT
+ def __eq__(self, other):
+ return isinstance(other, JvmBuiltInType) and other.name == self.name
+
+ def __hash__(self):
+ return hash(self.name)
+
def lookup_field(self, fieldnm):
""" Given a field name, returns a jvmgen.Field object """
_, FIELDTY = self.OOTYPE._lookup_field(fieldnm)
@@ -86,6 +92,9 @@
(ootype.String.__class__, "ll_streq"):
jvmgen.Method.v(jString, "equals", (jObject,), jBool),
+ (ootype.String.__class__, "ll_strlen"):
+ jvmgen.Method.v(jString, "length", (), jInt),
+
(ootype.List, "ll_length"):
jvmgen.Method.v(jArrayList, "size", (), jInt),
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Thu Jan 11 15:42:18 2007
@@ -243,11 +243,11 @@
_toString_methods = {
ootype.Signed:jvmgen.INTTOSTRINGI,
- ootype.Unsigned:jvmgen.PYPYDUMPUINT,
+ ootype.Unsigned:jvmgen.PYPYSERIALIZEUINT,
ootype.SignedLongLong:jvmgen.LONGTOSTRINGL,
ootype.Float:jvmgen.DOUBLETOSTRINGD,
- ootype.Bool:jvmgen.PYPYDUMPBOOLEAN,
- ootype.Void:jvmgen.PYPYDUMPVOID,
+ ootype.Bool:jvmgen.PYPYSERIALIZEBOOLEAN,
+ ootype.Void:jvmgen.PYPYSERIALIZEVOID,
ootype.Char:jvmgen.PYPYESCAPEDCHAR,
ootype.String:jvmgen.PYPYESCAPEDSTRING,
}
@@ -266,7 +266,7 @@
to print the value of 'var'.
"""
- return self._toString_methods.get(OOTYPE, jvmgen.OBJTOSTRING)
+ return self._toString_methods.get(OOTYPE, jvmgen.PYPYSERIALIZEOBJECT)
# _________________________________________________________________
# Type translation functions
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 15:42:18 2007
@@ -358,11 +358,12 @@
PYPYSTRTODOUBLE = Method.s(jPyPy, 'str_to_double', (jString,), jDouble)
PYPYSTRTOCHAR = Method.s(jPyPy, 'str_to_char', (jString,), jChar)
PYPYDUMP = Method.s(jPyPy, 'dump', (jString,), jVoid)
-PYPYDUMPBOOLEAN = Method.s(jPyPy, 'dump_boolean', (jBool,), jString)
-PYPYDUMPUINT = Method.s(jPyPy, 'dump_uint', (jInt,), jString)
-PYPYDUMPVOID = Method.s(jPyPy, 'dump_void', (), jString)
+PYPYSERIALIZEBOOLEAN = Method.s(jPyPy, 'serialize_boolean', (jBool,), jString)
+PYPYSERIALIZEUINT = Method.s(jPyPy, 'serialize_uint', (jInt,), jString)
+PYPYSERIALIZEVOID = Method.s(jPyPy, 'serialize_void', (), jString)
PYPYESCAPEDCHAR = Method.s(jPyPy, 'escaped_char', (jChar,), jString)
PYPYESCAPEDSTRING = Method.s(jPyPy, 'escaped_string', (jString,), jString)
+PYPYSERIALIZEOBJECT = Method.s(jPyPy, 'serializeObject', (jObject,), jString)
PYPYDUMPEXCWRAPPER = Method.s(jPyPy, 'dump_exc_wrapper', (jObject,), jVoid)
PYPYRUNTIMENEW = Method.s(jPyPy, 'RuntimeNew', (jClass,), jObject)
PYPYSTRING2BYTES = Method.s(jPyPy, 'string2bytes', (jString,), jByteArray)
@@ -922,15 +923,18 @@
elif TYPE is ootype.Float:
self._push_double_constant(float(value))
elif TYPE is ootype.String:
- self.load_string(str(value._str))
+ if value == ootype.null(ootype.String):
+ self.emit(ACONST_NULL)
+ else:
+ self.load_string(str(value._str))
def _push_long_constant(self, value):
if value == 0:
- gen.emit(LCONST_0)
+ self.emit(LCONST_0)
elif value == 1:
- gen.emit(LCONST_1)
+ self.emit(LCONST_1)
else:
- gen.emit(LDC2, value)
+ self.emit(LDC2, value)
def _push_double_constant(self, value):
if _isnan(value):
@@ -939,11 +943,11 @@
if value > 0: DOUBLEPOSINF.load(self)
else: DOUBLENEGINF.load(self)
elif value == 0.0:
- gen.emit(DCONST_0)
+ self.emit(DCONST_0)
elif value == 1.0:
- gen.emit(DCONST_1)
+ self.emit(DCONST_1)
else:
- gen.emit(LDC2, self.value)
+ self.emit(LDC2, value)
# __________________________________________________________________
# Methods invoked directly by strings in jvm/opcode.py
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 15:42:18 2007
@@ -115,6 +115,8 @@
done_printing = gen.unique_label('done_printing')
RESOOTYPE = self.graph.getreturnvar().concretetype
dumpmethod = self.db.generate_toString_method_for_ootype(RESOOTYPE)
+ gen.add_comment('Invoking dump method for result of type '
+ +str(RESOOTYPE))
gen.emit(dumpmethod) # generate the string
gen.emit(jvmgen.PYPYDUMP) # dump to stdout
gen.goto(done_printing)
@@ -356,8 +358,7 @@
if not i: continue # skip the this ptr
gen.load_function_argument(i)
gen.emit(self.impl_method)
- if self.super_class.java_return_type is not jVoid:
- gen.return_val(self.super_class.java_return_type)
+ gen.return_val(self.super_class.java_return_type)
gen.end_function()
gen.end_class()
Modified: pypy/dist/pypy/translator/jvm/src/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/PyPy.java Thu Jan 11 15:42:18 2007
@@ -192,11 +192,11 @@
System.out.println(text);
}
- public static String dump_void() {
+ public static String serialize_void() {
return "None";
}
- public static String dump_uint(int i) {
+ public static String serialize_uint(int i) {
if (i >= 0)
return Integer.toString(i);
else {
@@ -207,7 +207,7 @@
}
}
- public static String dump_boolean(boolean l) {
+ public static String serialize_boolean(boolean l) {
if (l)
return "True";
else
@@ -230,6 +230,8 @@
}
public static String escaped_string(String b) {
+ if (b == null)
+ return "None";
StringBuffer sb = new StringBuffer();
sb.append('"');
for (int i = 0; i < b.length(); i++) {
@@ -252,6 +254,12 @@
dump(sb.toString());
}
+ public static String serializeObject(Object o) {
+ if (o == null)
+ return "None";
+ return o.toString();
+ }
+
// ----------------------------------------------------------------------
// String
From mwh at codespeak.net Thu Jan 11 15:45:55 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Thu, 11 Jan 2007 15:45:55 +0100 (CET)
Subject: [pypy-svn] r36489 - pypy/dist/pypy/objspace/std
Message-ID: <20070111144555.77BF110075@code0.codespeak.net>
Author: mwh
Date: Thu Jan 11 15:45:53 2007
New Revision: 36489
Modified:
pypy/dist/pypy/objspace/std/dicttype.py
Log:
(mwh, cfbolz)
maaaaybe this will help with the ./startcompile.py --objspace-std-withmultidict problems.
Modified: pypy/dist/pypy/objspace/std/dicttype.py
==============================================================================
--- pypy/dist/pypy/objspace/std/dicttype.py (original)
+++ pypy/dist/pypy/objspace/std/dicttype.py Thu Jan 11 15:45:53 2007
@@ -141,7 +141,7 @@
dict_typedef = StdTypeDef("dict",
__doc__ = '''dict() -> new empty dictionary.
-dict(mapping) -> new dictionary initialized from a mapping object's
+dict(mapping) -> new dictionary initialized from a mapping object\'s
(key, value) pairs.
dict(seq) -> new dictionary initialized as if via:
d = {}
@@ -179,6 +179,10 @@
w_typeobj = space.gettypeobject(dictiter_typedef)
from pypy.interpreter.mixedmodule import MixedModule
+ if space.config.objspace.std.withmultidict:
+ raise OperationError(
+ space.w_RuntimeError,
+ space.wrap("cannot pickle dictiters with multidicts"))
if space.config.objspace.std.withstrdict:
from pypy.objspace.std.dictstrobject import \
W_DictStrIter_Keys as W_DictIter_Keys, \
From fijal at codespeak.net Thu Jan 11 15:55:36 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 15:55:36 +0100 (CET)
Subject: [pypy-svn] r36490 - pypy/dist/pypy/annotation/test
Message-ID: <20070111145536.3A64010075@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 15:55:34 2007
New Revision: 36490
Modified:
pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
(arigo, fijal) - Fix the unimplemented test, so it now resembles more what
we want to achieve.
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Thu Jan 11 15:55:34 2007
@@ -2452,24 +2452,26 @@
def test_some_generic_function_call(self):
py.test.skip("Not implemented")
- def g(a, b, c):
+ def g(a):
pass
- g.known_signature = FunctionSignature(args=(3, 3, 3), retval=3)
+ g._known_signature_ = annmodel.SomeGenericFunction(
+ args=(annmodel.SomeInteger(),), retval=annmodel.SomeInteger())
def fun():
- return g(1, 2, 3)
+ return g(1)
a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
s = a.build_types(fun, [])
assert isinstance(s.returntype, annmodel.SomeInteger)
assert not hasattr(s.returntype, 'const')
# assert that a know the g
- def test_some_genereic_function_callback(self):
+ def test_some_generic_function_callback(self):
py.test.skip("Not implemented")
def g(a):
pass
- g.known_signature = FunctionSignature(args=
- [FunctionSignature(args=[1])], retval=3)
+ g._known_signature_ = annmodel.SomeGenericFunction(
+ args=[annmodel.SomeGenericFunction(args=[SomeInteger()],
+ retval=SomeInteger())])
def fun2(x):
return x
From pedronis at codespeak.net Thu Jan 11 16:05:11 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Thu, 11 Jan 2007 16:05:11 +0100 (CET)
Subject: [pypy-svn] r36491 - pypy/dist/pypy/jit
Message-ID: <20070111150511.0117310075@code0.codespeak.net>
Author: pedronis
Date: Thu Jan 11 16:05:10 2007
New Revision: 36491
Modified:
pypy/dist/pypy/jit/TODO.txt
Log:
oops, an open issue to think about when we have more experience with virtualizable.
In theory we could generate different code and detect which one to use at runtime based on aliasing
checks but well...
Modified: pypy/dist/pypy/jit/TODO.txt
==============================================================================
--- pypy/dist/pypy/jit/TODO.txt (original)
+++ pypy/dist/pypy/jit/TODO.txt Thu Jan 11 16:05:10 2007
@@ -15,6 +15,11 @@
- make backend opts usable on the interp+timeshifted interp graph forest
+Open issues
+--------------
+
+- think about aliasing issues with virtualizables
+
Improvements
-------------
From fijal at codespeak.net Thu Jan 11 16:08:21 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 16:08:21 +0100 (CET)
Subject: [pypy-svn] r36494 - pypy/dist/pypy/tool/test
Message-ID: <20070111150821.6A5F310080@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 16:08:20 2007
New Revision: 36494
Modified:
pypy/dist/pypy/tool/test/test_conftest1.py
Log:
Adhere to new pylib semantics
Modified: pypy/dist/pypy/tool/test/test_conftest1.py
==============================================================================
--- pypy/dist/pypy/tool/test/test_conftest1.py (original)
+++ pypy/dist/pypy/tool/test/test_conftest1.py Thu Jan 11 16:08:20 2007
@@ -2,11 +2,12 @@
import py
innertest = py.magic.autopath().dirpath('conftest1_innertest.py')
+from py.__.test.terminal.terminal import TerminalSession
class TestPyPyTests:
def test_select_interplevel(self):
config, args = py.test.Config.parse(['-k', 'interplevel'])
- session = py.test.TerminalSession(config, py.std.sys.stdout)
+ session = TerminalSession(config, py.std.sys.stdout)
session.main([innertest])
l = session.getitemoutcomepairs(py.test.Item.Passed)
assert len(l) == 2
@@ -21,7 +22,7 @@
def test_select_applevel(self):
config, args = py.test.Config.parse(['-k', 'applevel'])
- session = py.test.TerminalSession(config, py.std.sys.stdout)
+ session = TerminalSession(config, py.std.sys.stdout)
session.main([innertest])
l = session.getitemoutcomepairs(py.test.Item.Passed)
assert len(l) == 2
@@ -36,7 +37,7 @@
def XXX_test_appdirect(self):
config, args = py.test.Config.parse(['-k', 'applevel', '--appdirect', str(innertest)])
- session = py.test.TerminalSession(config, py.std.sys.stdout)
+ session = TerminalSession(config, py.std.sys.stdout)
session.main([innertest])
l = session.getitemoutcomepairs(py.test.Item.Passed)
assert len(l) == 2
From pedronis at codespeak.net Thu Jan 11 16:25:36 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Thu, 11 Jan 2007 16:25:36 +0100 (CET)
Subject: [pypy-svn] r36499 - in pypy/dist/pypy/jit/timeshifter: . test
Message-ID: <20070111152536.2875C10072@code0.codespeak.net>
Author: pedronis
Date: Thu Jan 11 16:25:34 2007
New Revision: 36499
Modified:
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/rvalue.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
support receiving a virtualizable from the outside world through a read (getfield).
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Thu Jan 11 16:25:34 2007
@@ -135,17 +135,24 @@
class FieldDesc(object):
__metaclass__ = cachedtype
allow_void = False
+ virtualizable = False
def __init__(self, RGenOp, PTRTYPE, RESTYPE):
self.PTRTYPE = PTRTYPE
if isinstance(RESTYPE, lltype.ContainerType):
RESTYPE = lltype.Ptr(RESTYPE)
+ elif isinstance(RESTYPE, lltype.Ptr):
+ T = RESTYPE.TO
+ if hasattr(T, '_hints'):
+ self.virtualizable = T._hints.get('virtualizable', False)
self.RESTYPE = RESTYPE
self.ptrkind = RGenOp.kindToken(PTRTYPE)
self.kind = RGenOp.kindToken(RESTYPE)
self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
if RESTYPE is lltype.Void and self.allow_void:
pass # no redboxcls at all
+ elif self.virtualizable:
+ self.structdesc = StructTypeDesc(RGenOp, T)
else:
self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
self.immutable = PTRTYPE.TO._hints.get('immutable', False)
@@ -154,9 +161,17 @@
return True
def makedefaultbox(self):
+ if self.virtualizable:
+ return self.structdesc.factory()
return self.redboxcls(self.kind, self.gv_default)
- def makebox(self, gvar):
+ def makebox(self, jitstate, gvar):
+ if self.virtualizable:
+ structbox = self.structdesc.factory()
+ content = structbox.content
+ assert isinstance(content, VirtualizableStruct)
+ content.load_from(jitstate, gvar)
+ return structbox
return self.redboxcls(self.kind, gvar)
class NamedFieldDesc(FieldDesc):
@@ -170,16 +185,19 @@
def compact_repr(self): # goes in ll helper names
return "Fld_%s_in_%s" % (self.fieldname, self.PTRTYPE._short_name())
- def generate_get(self, builder, genvar):
+ def generate_get(self, jitstate, genvar):
+ builder = jitstate.curbuilder
gv_item = builder.genop_getfield(self.fieldtoken, genvar)
- return self.makebox(gv_item)
+ return self.makebox(jitstate, gv_item)
- def generate_set(self, builder, genvar, gv_value):
+ def generate_set(self, jitstate, genvar, gv_value):
+ builder = jitstate.curbuilder
builder.genop_setfield(self.fieldtoken, genvar, gv_value)
- def generate_getsubstruct(self, builder, genvar):
+ def generate_getsubstruct(self, jitstate, genvar):
+ builder = jitstate.curbuilder
gv_sub = builder.genop_getsubstruct(self.fieldtoken, genvar)
- return self.makebox(gv_sub)
+ return self.makebox(jitstate, gv_sub)
class StructFieldDesc(NamedFieldDesc):
@@ -292,7 +310,7 @@
for i in range(len(fielddescs)):
fielddesc = fielddescs[i]
box = boxes[i]
- fielddesc.generate_set(builder, genvar, box.getgenvar(jitstate))
+ fielddesc.generate_set(jitstate, genvar, box.getgenvar(jitstate))
def freeze(self, memo):
contmemo = memo.containers
@@ -356,9 +374,18 @@
for i in range(1, len(fielddescs)):
fielddesc = fielddescs[i]
box = boxes[i]
- fielddesc.generate_set(jitstate.curbuilder, gv_outside,
+ fielddesc.generate_set(jitstate, gv_outside,
box.getgenvar(jitstate))
+ def load_from(self, jitstate, gv_outside):
+ fielddescs = self.typedesc.fielddescs
+ boxes = self.content_boxes
+ boxes[-1].genvar = gv_outside
+ for i in range(1, len(fielddescs)):
+ fielddesc = fielddescs[i]
+ boxes[i] = fielddesc.generate_get(jitstate, gv_outside)
+ jitstate.add_virtualizable(self.ownbox)
+
# ____________________________________________________________
class FrozenPartialDataStruct(AbstractContainer):
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Thu Jan 11 16:25:34 2007
@@ -128,7 +128,7 @@
argbox.getgenvar(jitstate),
indexbox.getgenvar(jitstate))
- return fielddesc.makebox(genvar)
+ return fielddesc.makebox(jitstate, genvar)
def ll_gengetarraysubstruct(jitstate, fielddesc, argbox, indexbox):
if argbox.is_constant() and indexbox.is_constant():
@@ -140,7 +140,7 @@
argbox.getgenvar(jitstate),
indexbox.getgenvar(jitstate))
- return fielddesc.makebox(genvar)
+ return fielddesc.makebox(jitstate, genvar)
def ll_gensetarrayitem(jitstate, fielddesc, destbox, indexbox, valuebox):
Modified: pypy/dist/pypy/jit/timeshifter/rvalue.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rvalue.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rvalue.py Thu Jan 11 16:25:34 2007
@@ -190,7 +190,7 @@
if box is not None:
return box
gv_ptr = self.getgenvar(jitstate)
- box = fielddesc.generate_get(jitstate.curbuilder, gv_ptr)
+ box = fielddesc.generate_get(jitstate, gv_ptr)
if fielddesc.immutable:
self.remember_field(fielddesc, box)
return box
@@ -198,7 +198,7 @@
def op_setfield(self, jitstate, fielddesc, valuebox):
gv_ptr = self.genvar
if gv_ptr:
- fielddesc.generate_set(jitstate.curbuilder, gv_ptr,
+ fielddesc.generate_set(jitstate, gv_ptr,
valuebox.getgenvar(jitstate))
else:
assert self.content is not None
@@ -207,7 +207,7 @@
def op_getsubstruct(self, jitstate, fielddesc):
gv_ptr = self.genvar
if gv_ptr:
- return fielddesc.generate_getsubstruct(jitstate.curbuilder, gv_ptr)
+ return fielddesc.generate_getsubstruct(jitstate, gv_ptr)
else:
assert self.content is not None
return self.content.op_getsubstruct(jitstate, fielddesc)
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Thu Jan 11 16:25:34 2007
@@ -408,7 +408,6 @@
self.check_insns(getfield=0, malloc=2)
def test_simple_explicit_read(self):
- py.test.skip("WIP")
def f(e):
xy = e.xy
From pedronis at codespeak.net Thu Jan 11 16:33:56 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Thu, 11 Jan 2007 16:33:56 +0100 (CET)
Subject: [pypy-svn] r36500 - pypy/dist/pypy/jit/timeshifter/test
Message-ID: <20070111153356.E933610071@code0.codespeak.net>
Author: pedronis
Date: Thu Jan 11 16:33:55 2007
New Revision: 36500
Modified:
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
an already passing test about virtualizable escaping through a forced virtual struct
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Thu Jan 11 16:33:55 2007
@@ -431,3 +431,34 @@
res = self.timeshift_from_portal(main, f, [20, 22], policy=P_NOVIRTUAL)
assert res == 63
self.check_insns(getfield=3)
+
+ def test_simple_explicit_escape_through_vstruct(self):
+
+ def f(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ e = lltype.malloc(E)
+ e.xy = xy
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ xy_access = xy.access
+ newy = 2*y
+ if xy_access:
+ xy_access.set_y(xy, newy)
+ else:
+ xy.y = newy
+ return e
+
+ def main(x, y):
+ e = f(x, y)
+ return e.xy.x+e.xy.y
+
+ res = self.timeshift_from_portal(main, f, [20, 11], policy=P_NOVIRTUAL)
+ assert res == 42
+ self.check_insns(getfield=0, malloc=2)
+
From afayolle at codespeak.net Thu Jan 11 16:35:14 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Thu, 11 Jan 2007 16:35:14 +0100 (CET)
Subject: [pypy-svn] r36501 - pypy/dist/pypy/module/bz2
Message-ID: <20070111153514.C737A10071@code0.codespeak.net>
Author: afayolle
Date: Thu Jan 11 16:35:14 2007
New Revision: 36501
Modified:
pypy/dist/pypy/module/bz2/interp_bz2.py
Log:
(arigo, cfboltz, afayolle) - do not use cdll.LoadLibrary to load libbz2 (which caused -lbz2 not to be passed to the linker)
Modified: pypy/dist/pypy/module/bz2/interp_bz2.py
==============================================================================
--- pypy/dist/pypy/module/bz2/interp_bz2.py (original)
+++ pypy/dist/pypy/module/bz2/interp_bz2.py Thu Jan 11 16:35:14 2007
@@ -12,7 +12,7 @@
from bzlib import bz_stream, BZFILE, FILE
-libbz2 = cdll.LoadLibrary(ctypes.util.find_library("bz2"))
+#libbz2 = cdll.LoadLibrary(ctypes.util.find_library("bz2"))
c_void = None
@@ -22,9 +22,9 @@
#include
#include
"""
- # XXX: with this it should compile fine but on my machine pypy doesn't
- # inject this header so it's pretty useless. Kept as a remind.
- # _includes_ = ["bzlib.h"]
+
+ _includes_ = ["bzlib.h"]
+ libbz2 = ctypes_platform.Library('bz2')
off_t = ctypes_platform.SimpleType("off_t", c_longlong)
size_t = ctypes_platform.SimpleType("size_t", c_ulong)
BUFSIZ = ctypes_platform.ConstantInteger("BUFSIZ")
@@ -49,6 +49,7 @@
constants[name] = value
locals().update(constants)
+libbz2 = cConfig.libbz2
off_t = cConfig.off_t
BUFSIZ = cConfig.BUFSIZ
SEEK_SET = cConfig.SEEK_SET
From arigo at codespeak.net Thu Jan 11 16:40:04 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Thu, 11 Jan 2007 16:40:04 +0100 (CET)
Subject: [pypy-svn] r36502 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070111154004.C661410072@code0.codespeak.net>
Author: arigo
Date: Thu Jan 11 16:40:03 2007
New Revision: 36502
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Progress on keep condition codes in the processor's condition codes.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Thu Jan 11 16:40:03 2007
@@ -2,15 +2,25 @@
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
+from pypy.objspace.std.multimethod import FailedToImplement
from pypy.jit.codegen.i386.ri386 import *
+from pypy.jit.codegen.i386.ri386setup import Conditions
from pypy.jit.codegen.i386 import conftest
WORD = 4 # bytes
+RK_NO_RESULT = 0
+RK_WORD = 1
+RK_CC = 2
+
class Operation(GenVar):
- def allocate_registers(self, allocator):
+ clobbers_cc = True
+ result_kind = RK_WORD
+ cc_result = -1
+
+ def allocate(self, allocator):
pass
def generate(self, allocator):
raise NotImplementedError
@@ -18,7 +28,7 @@
class Op1(Operation):
def __init__(self, x):
self.x = x
- def allocate_registers(self, allocator):
+ def allocate(self, allocator):
allocator.using(self.x)
def generate(self, allocator):
try:
@@ -30,13 +40,46 @@
allocator.store_back_location(loc, op)
class OpSameAs(Op1):
- emit = staticmethod(lambda mc, x: None)
+ clobbers_cc = False
+ def generate(self, allocator):
+ try:
+ dstop = allocator.get_operand(self)
+ except KeyError:
+ return # result not used
+ srcop = self.get_operand(self.x)
+ if srcop != dstop:
+ try:
+ self.mc.MOV(dstop, srcop)
+ except FailedToImplement:
+ self.mc.MOV(ecx, srcop)
+ self.mc.MOV(dstop, ecx)
+ return dstop
+
+class OpCompare1(Op1):
+ result_kind = RK_CC
+ def generate(self, allocator):
+ srcop = allocator.get_operand(self.x)
+ dstop = allocator.get_operand(self.y)
+ mc = allocator.mc
+ # XXX optimize the case CMP(immed, reg-or-modrm)
+ try:
+ mc.CMP(srcop, dstop)
+ except FailedToImplement:
+ mc.MOV(ecx, srcop)
+ mc.CMP(ecx, dstop)
+
+class OpIntIsTrue(OpCompare1):
+ opname = 'int_is_true'
+ cc_result = I386CodeBuilder.JNE
+ @staticmethod
+ def emit(mc, x):
+ mc.CMP(x, imm8(0))
class Op2(Operation):
def __init__(self, x, y):
self.x = x
self.y = y
- def allocate_registers(self, allocator):
+ def allocate(self, allocator):
allocator.using(self.x)
allocator.using(self.y)
def generate(self, allocator):
@@ -57,26 +100,37 @@
opname = 'int_sub'
emit = staticmethod(I386CodeBuilder.SUB)
-class OpIntGt(Op2):
+class OpCompare2(Op2):
+ result_kind = RK_CC
+ def generate(self, allocator):
+ srcop = allocator.get_operand(self.x)
+ dstop = allocator.get_operand(self.y)
+ mc = allocator.mc
+ # XXX optimize the case CMP(immed, reg-or-modrm)
+ try:
+ mc.CMP(srcop, dstop)
+ except FailedToImplement:
+ mc.MOV(ecx, srcop)
+ mc.CMP(ecx, dstop)
+
+class OpIntGt(OpCompare2):
opname = 'int_gt'
- @staticmethod
- def emit(mc, x, y):
- mc.CMP(x, y)
- mc.SETG(cl)
- mc.MOVZX(x, cl)
+ cc_result = Conditions['G']
class JumpIfFalse(Operation):
+ clobbers_cc = False
+ result_kind = RK_NO_RESULT
def __init__(self, gv_condition, targetbuilder):
+ assert 0 <= gv_condition.cc_result < INSN_JMP
self.gv_condition = gv_condition
self.targetbuilder = targetbuilder
- def allocate_registers(self, allocator):
- allocator.using(self.gv_condition)
+ def allocate(self, allocator):
+ allocator.using_cc(self.gv_condition)
def generate(self, allocator):
- op = allocator.get_operand(self.gv_condition)
+ cc = cond_negate(self.gv_condition.cc_result)
mc = allocator.mc
- mc.CMP(op, imm8(0))
targetbuilder = self.targetbuilder
- targetbuilder.set_coming_from(mc, insn=I386CodeBuilder.JE)
+ targetbuilder.set_coming_from(mc, insncond=cc)
targetbuilder.inputoperands = [allocator.get_operand(gv)
for gv in targetbuilder.inputargs_gv]
@@ -157,7 +211,19 @@
OPCLASSES2 = setup_opclasses(Op2)
del setup_opclasses
-OPCLASSES1['int_is_true'] = None
+def setup_conditions():
+ result = [None] * 16
+ for key, value in Conditions.items():
+ result[value] = getattr(I386CodeBuilder, 'J'+key)
+ return result
+EMIT_CONDITION = setup_conditions()
+INSN_JMP = len(EMIT_CONDITION)
+EMIT_CONDITION.append(I386CodeBuilder.JMP)
+del setup_conditions
+
+def cond_negate(cond):
+ assert 0 <= cond < INSN_JMP
+ return cond ^ 1
class StackOpCache:
@@ -221,13 +287,44 @@
self.nextloc += 1
self.var2loc[v] = loc
+ def creating_cc(self, v):
+ if self.need_var_in_cc is v:
+ # common case: v is a compare operation whose result is precisely
+ # what we need to be in the CC
+ self.need_var_in_cc = None
+
+ def save_cc(self):
+ # we need a value to be in the CC, but we see a clobbering
+ # operation, so we copy the original CC-creating operation down
+ # past the clobbering operation
+ v = self.need_var_in_cc
+ self.operations.insert(self.operationindex, v)
+ self.need_var_in_cc = None
+
+ def using_cc(self, v):
+ assert not v.is_const
+ if self.need_var_in_cc is not None:
+ self.save_cc()
+ self.need_var_in_cc = v
+
def allocate_locations(self, operations):
# assign locations to gvars
self.operations = operations
+ self.need_var_in_cc = None
+ self.operationindex = len(operations)
for i in range(len(operations)-1, -1, -1):
v = operations[i]
- self.creating(v)
- v.allocate_registers(self)
+ kind = v.result_kind
+ if kind == RK_WORD:
+ self.creating(v)
+ elif kind == RK_CC:
+ self.creating_cc(v)
+ if self.need_var_in_cc is not None and v.clobbers_cc:
+ self.save_cc()
+ v.allocate(self)
+ self.operationindex = i
+ if self.need_var_in_cc is not None:
+ self.save_cc()
def force_var_operands(self, force_vars, force_operands, at_start):
force_loc2operand = self.force_loc2operand
@@ -358,10 +455,11 @@
self.rgenop.close_mc(mc)
self.start_writing()
- def set_coming_from(self, mc, insn=I386CodeBuilder.JMP):
- self.coming_from_insn = insn
+ def set_coming_from(self, mc, insncond=INSN_JMP):
+ self.coming_from_cond = insncond
self.coming_from = mc.tell()
- insn(mc, rel32(0))
+ insnemit = EMIT_CONDITION[insncond]
+ insnemit(mc, rel32(0))
def start_mc(self):
mc = self.rgenop.open_mc()
@@ -371,7 +469,7 @@
targetaddr = mc.tell()
end = start + 6 # XXX hard-coded, enough for JMP and Jcond
oldmc = self.rgenop.InMemoryCodeBuilder(start, end)
- insn = self.coming_from_insn
+ insn = EMIT_CONDITION[self.coming_from_cond]
insn(oldmc, rel32(targetaddr))
oldmc.done()
self.coming_from = 0
@@ -379,6 +477,9 @@
def jump_if_false(self, gv_condition, args_for_jump_gv):
newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None)
+ if gv_condition.cc_result < 0:
+ gv_condition = OpIntIsTrue(gv_condition)
+ self.operations.append(gv_condition)
self.operations.append(JumpIfFalse(gv_condition, newbuilder))
return newbuilder
From fijal at codespeak.net Thu Jan 11 16:44:31 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 16:44:31 +0100 (CET)
Subject: [pypy-svn] r36504 - pypy/dist/pypy/annotation
Message-ID: <20070111154431.2A29010075@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 16:44:27 2007
New Revision: 36504
Modified:
pypy/dist/pypy/annotation/bookkeeper.py
Log:
Kill dead code
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Thu Jan 11 16:44:27 2007
@@ -453,109 +453,6 @@
def annotation_from_example(self, x):
# XXX to kill at some point
return self.immutablevalue(x, False)
-
-## def annotation_from_example(self, x):
-## """The most precise SomeValue instance that contains the
-## mutable value x."""
-## # convert unbound methods to the underlying function
-## if hasattr(x, 'im_self') and x.im_self is None:
-## x = x.im_func
-## assert not hasattr(x, 'im_self')
-## if x is sys: # special case constant sys to someobject
-## return SomeObject()
-## tp = type(x)
-## if issubclass(tp, Symbolic): # symbolic constants support
-## result = x.annotation()
-## return result
-## if tp is bool:
-## result = SomeBool()
-## elif tp is int:
-## result = SomeInteger(nonneg = x>=0)
-## elif issubclass(tp, str): # py.lib uses annotated str subclasses
-## if len(x) == 1:
-## result = SomeChar()
-## else:
-## result = SomeString()
-## elif tp is unicode and len(x) == 1:
-## result = SomeUnicodeCodePoint()
-## elif tp is tuple:
-## result = SomeTuple(items = [self.annotation_from_example(e) for e in x])
-## elif tp is float:
-## result = SomeFloat()
-## elif tp is list:
-## listdef = ListDef(self, s_ImpossibleValue)
-## for e in x:
-## listdef.generalize(self.annotation_from_example(e))
-## result = SomeList(listdef)
-## elif tp is dict or tp is r_dict:
-## dictdef = DictDef(self,
-## s_ImpossibleValue,
-## s_ImpossibleValue,
-## is_r_dict = tp is r_dict)
-## if tp is r_dict:
-## s_eqfn = self.immutablevalue(x.key_eq)
-## s_hashfn = self.immutablevalue(x.key_hash)
-## dictdef.dictkey.update_rdict_annotations(s_eqfn,
-## s_hashfn)
-## for ek, ev in x.iteritems():
-## dictdef.generalize_key(self.annotation_from_example(ek))
-## dictdef.generalize_value(self.annotation_from_example(ev))
-## result = SomeDict(dictdef)
-## elif ishashable(x) and x in BUILTIN_ANALYZERS:
-## _module = getattr(x,"__module__","unknown")
-## result = SomeBuiltin(BUILTIN_ANALYZERS[x], methodname="%s.%s" % (_module, x.__name__))
-## elif extregistry.is_registered(x, self.policy):
-## entry = extregistry.lookup(x, self.policy)
-## result = entry.compute_annotation_bk(self)
-#### elif hasattr(x, "compute_result_annotation"):
-#### result = SomeBuiltin(x.compute_result_annotation, methodname=x.__name__)
-#### elif hasattr(tp, "compute_annotation"):
-#### result = tp.compute_annotation()
-## elif tp in EXTERNAL_TYPE_ANALYZERS:
-## result = SomeExternalObject(tp)
-## elif isinstance(x, lltype._ptr):
-## result = SomePtr(lltype.typeOf(x))
-## elif isinstance(x, llmemory.fakeaddress):
-## result = SomeAddress(is_null=not x)
-## elif isinstance(x, llmemory.fakeweakaddress):
-## result = SomeWeakGcAddress()
-## elif isinstance(x, ootype._static_meth):
-## result = SomeOOStaticMeth(ootype.typeOf(x))
-## elif isinstance(x, ootype._class):
-## result = SomeOOClass(x._INSTANCE) # NB. can be None
-## elif isinstance(x, ootype.instance_impl): # XXX
-## result = SomeOOInstance(ootype.typeOf(x))
-## elif callable(x):
-## if hasattr(x, '__self__') and x.__self__ is not None:
-## # for cases like 'l.append' where 'l' is a global constant list
-## s_self = self.annotation_from_example(x.__self__)
-## result = s_self.find_method(x.__name__)
-## if result is None:
-## result = SomeObject()
-## else:
-## if (self.annotator.policy.allow_someobjects
-## and getattr(x, '__module__', None) == '__builtin__'
-## # XXX note that the print support functions are __builtin__
-## and tp not in (types.FunctionType, types.MethodType)):
-## result = SomeObject()
-## result.knowntype = tp # at least for types this needs to be correct
-## else:
-## result = SomePBC([self.getdesc(x)])
-## elif hasattr(x, '_freeze_') and x._freeze_():
-## # user-defined classes can define a method _freeze_(), which
-## # is called when a prebuilt instance is found. If the method
-## # returns True, the instance is considered immutable and becomes
-## # a SomePBC(). Otherwise it's just SomeInstance().
-## result = SomePBC([self.getdesc(x)])
-## elif hasattr(x, '__class__') \
-## and x.__class__.__module__ != '__builtin__':
-## self.see_mutable(x)
-## result = SomeInstance(self.getuniqueclassdef(x.__class__))
-## elif x is None:
-## return s_None
-## else:
-## result = SomeObject()
-## return result
def getdesc(self, pyobj):
# get the XxxDesc wrapper for the given Python object, which must be
From pedronis at codespeak.net Thu Jan 11 16:47:06 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Thu, 11 Jan 2007 16:47:06 +0100 (CET)
Subject: [pypy-svn] r36507 - pypy/dist/pypy/jit/timeshifter/test
Message-ID: <20070111154706.AF67F1007C@code0.codespeak.net>
Author: pedronis
Date: Thu Jan 11 16:47:03 2007
New Revision: 36507
Modified:
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
a test involving virtualizable and a residual call, this one already works because the virtualizable is not used across
the call so there's an early enough store back
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Thu Jan 11 16:47:03 2007
@@ -1,3 +1,4 @@
+from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
from pypy.jit.timeshifter.test.test_portal import PortalTest, P_NOVIRTUAL
from pypy.rpython.lltypesystem import lltype
@@ -42,7 +43,8 @@
hints = {'virtualizable': True}
))
-E = lltype.GcStruct('e', ('xy', lltype.Ptr(XY)))
+E = lltype.GcStruct('e', ('xy', lltype.Ptr(XY)),
+ ('w', lltype.Signed))
XP.become(lltype.GcStruct('xp',
('access', lltype.Ptr(XP_ACCESS)),
@@ -462,3 +464,51 @@
assert res == 42
self.check_insns(getfield=0, malloc=2)
+ def test_explicit_late_residual_red_call(self):
+ def g(e):
+ xy = e.xy
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ e.w = y
+
+ def f(e):
+ xy = e.xy
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ xy_access = xy.access
+ newy = 2*y
+ if xy_access:
+ xy_access.set_y(xy, newy)
+ else:
+ xy.y = newy
+ g(e)
+ return 0
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ e = lltype.malloc(E)
+ e.xy = xy
+ f(e)
+ return e.w
+
+
+ class StopAtGPolicy(HintAnnotatorPolicy):
+ novirtualcontainer = True
+
+ def look_inside_graph(self, graph):
+ if graph.name == 'g':
+ return False
+ return True
+
+ res = self.timeshift_from_portal(main, f, [0, 21],
+ policy=StopAtGPolicy())
+ assert res == 42
From fijal at codespeak.net Thu Jan 11 16:57:07 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 16:57:07 +0100 (CET)
Subject: [pypy-svn] r36508 - in pypy/dist/pypy/annotation: . test
Message-ID: <20070111155707.E293210071@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 16:57:06 2007
New Revision: 36508
Modified:
pypy/dist/pypy/annotation/bookkeeper.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/annotation/test/test_annrpython.py
pypy/dist/pypy/annotation/unaryop.py
Log:
Add possibility to call SomeGenericCallable
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Thu Jan 11 16:57:06 2007
@@ -409,6 +409,8 @@
result = SomeOOClass(x._INSTANCE) # NB. can be None
elif isinstance(x, ootype.instance_impl): # XXX
result = SomeOOInstance(ootype.typeOf(x))
+ elif hasattr(x, '_known_annotation_'):
+ result = x._known_annotation_
elif callable(x):
if hasattr(x, '__self__') and x.__self__ is not None:
# for cases like 'l.append' where 'l' is a global constant list
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Thu Jan 11 16:57:06 2007
@@ -393,6 +393,12 @@
else:
return kt.__name__
+class SomeGenericCallable(SomeObject):
+ """ Stands for external callable with known signature
+ """
+ def __init__(self, args, retval):
+ self.args_s = args
+ self.retval_s = retval
class SomeBuiltin(SomeObject):
"Stands for a built-in function or method with special-cased analysis."
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Thu Jan 11 16:57:06 2007
@@ -2451,26 +2451,24 @@
assert s.const == 0
def test_some_generic_function_call(self):
- py.test.skip("Not implemented")
def g(a):
pass
- g._known_signature_ = annmodel.SomeGenericFunction(
+ g._known_annotation_ = annmodel.SomeGenericCallable(
args=(annmodel.SomeInteger(),), retval=annmodel.SomeInteger())
def fun():
return g(1)
a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
s = a.build_types(fun, [])
- assert isinstance(s.returntype, annmodel.SomeInteger)
- assert not hasattr(s.returntype, 'const')
- # assert that a know the g
+ assert isinstance(s, annmodel.SomeInteger)
+ assert not hasattr(s, 'const')
def test_some_generic_function_callback(self):
py.test.skip("Not implemented")
def g(a):
pass
- g._known_signature_ = annmodel.SomeGenericFunction(
- args=[annmodel.SomeGenericFunction(args=[SomeInteger()],
+ g._known_annotation_ = annmodel.SomeGenericCallable(
+ args=[annmodel.SomeGenericCallable(args=[SomeInteger()],
retval=SomeInteger())])
def fun2(x):
Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py (original)
+++ pypy/dist/pypy/annotation/unaryop.py Thu Jan 11 16:57:06 2007
@@ -8,7 +8,8 @@
SomeInstance, SomeBuiltin, SomeFloat, SomeIterator, SomePBC, \
SomeExternalObject, SomeTypedAddressAccess, SomeAddress, \
SomeCTypesObject, s_ImpossibleValue, s_Bool, \
- unionof, set, missing_operation, add_knowntypedata, HarmlesslyBlocked
+ unionof, set, missing_operation, add_knowntypedata, HarmlesslyBlocked, \
+ SomeGenericCallable
from pypy.annotation.bookkeeper import getbookkeeper
from pypy.annotation import builtin
from pypy.annotation.binaryop import _clone ## XXX where to put this?
@@ -599,6 +600,12 @@
elif not pbc.can_be_None:
s.const = True
+class __extend__(SomeGenericCallable):
+ def call(self, args):
+ bookkeeper = getbookkeeper()
+ for arg, expected in zip(args.unpack()[0], self.args_s):
+ assert expected.contains(arg)
+ return self.retval_s
class __extend__(SomeExternalObject):
def find_method(obj, name):
From ericvrp at codespeak.net Thu Jan 11 17:02:02 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Thu, 11 Jan 2007 17:02:02 +0100 (CET)
Subject: [pypy-svn] r36510 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070111160202.411EB10079@code0.codespeak.net>
Author: ericvrp
Date: Thu Jan 11 17:02:01 2007
New Revision: 36510
Modified:
pypy/dist/pypy/jit/codegen/llvm/compatibility.py
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
Log:
(ericvrp, arigo around)
Do the right thing in get/setarrayitem and get/setfield.
Use doubles instead of floats.
Malloc's now always return i8 pointers that later get cas to the correct type.
fieldToken and arrayToken no longer return sizes because we need the actual type
for proper casts.
Modified: pypy/dist/pypy/jit/codegen/llvm/compatibility.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/compatibility.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/compatibility.py Thu Jan 11 17:02:01 2007
@@ -28,3 +28,5 @@
i16 = 'i16'
i32 = 'i32'
i64 = 'i64'
+
+f64 = 'double'
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Thu Jan 11 17:02:01 2007
@@ -8,15 +8,16 @@
from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr
from pypy.jit.codegen.llvm.conftest import option
from pypy.jit.codegen.llvm.compatibility import icmp, scmp, ucmp, fcmp, inttoptr,\
- trunc, zext, bitcast, shr_prefix, define, i8, i16, i32
+ trunc, zext, bitcast, shr_prefix, define, i8, i16, i32, f64
+pi8 = i8 + '*'
+u32 = i32
+
LINENO = option.lineno
PRINT_SOURCE = option.print_source
PRINT_DEBUG = option.print_debug
-WORD = 4
-
class ParseException(Exception):
pass
@@ -89,7 +90,7 @@
def __init__(self, type):
self.n = count.n_vars
self.type = type
- self.signed = type is i32 or type is 'float'
+ self.signed = type is i32 or type is f64
count.n_vars += 1
def operand(self):
@@ -165,7 +166,7 @@
class UIntConst(GenericConst):
- type = i32 #'uint'
+ type = u32
signed = False
def __init__(self, value):
@@ -173,7 +174,7 @@
class FloatConst(GenericConst):
- type = 'float'
+ type = f64
signed = True
def __init__(self, value):
@@ -181,7 +182,7 @@
class AddrConst(GenConst):
- type = i32 + '*'
+ type = pi8
signed = False
def __init__(self, addr):
@@ -556,15 +557,15 @@
def _cast_to_char(self, gv_x): return self._cast_to(gv_x, i8)
def _cast_to_unichar(self, gv_x): return self._cast_to(gv_x, i32)
def _cast_to_int(self, gv_x): return self._cast_to(gv_x, i32)
- def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, i32) #'uint')
- def _cast_to_float(self, gv_x): return self._cast_to(gv_x, 'float')
+ def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, u32)
+ def _cast_to_float(self, gv_x): return self._cast_to(gv_x, f64)
def _trunc_to_bool(self, gv_x): return self._trunc_to(gv_x, 'bool')
def _trunc_to_char(self, gv_x): return self._trunc_to(gv_x, i8)
def _trunc_to_unichar(self, gv_x): return self._trunc_to(gv_x, i32)
def _trunc_to_int(self, gv_x): return self._trunc_to(gv_x, i32)
- def _trunc_to_uint(self, gv_x): return self._trunc_to(gv_x, i32) #'uint')
- def _trunc_to_float(self, gv_x): return self._trunc_to(gv_x, 'float')
+ def _trunc_to_uint(self, gv_x): return self._trunc_to(gv_x, u32)
+ def _trunc_to_float(self, gv_x): return self._trunc_to(gv_x, f64)
op_cast_char_to_bool = _trunc_to_bool
op_cast_unichar_to_bool = _trunc_to_bool
@@ -668,81 +669,44 @@
op_ptr_iszero = _is_false
- def op_float_is_true(self, gv_x): return self._is_true(gv_x, '0.0')
+ def op_float_is_true(self, gv_x): return self._is_true(gv_x, '0.0') #XXX fails for doubles
- def genop_getfield(self, (offset, fieldsize), gv_ptr):
- log('%s Builder.genop_getfield (%d,%d) %s' % (
- self.block.label, offset, fieldsize, gv_ptr.operand()))
- if fieldsize == WORD:
- t = i32
- else:
- if fieldsize == 1:
- t = i8
- else:
- if fieldsize != 2:
- logger.dump('assert fails on: fieldsize != [124]')
- self.rgenop._dump_partial_lines()
- assert fieldsize == 2
- t = i16
+ def genop_getfield(self, fieldtoken, gv_ptr):
+ offset, fieldtype = fieldtoken
+ log('%s Builder.genop_getfield (%d,%s) %s' % (
+ self.block.label, offset, fieldtype, gv_ptr.operand()))
gv_ptr_var = self._as_var(gv_ptr)
- gv_p = Var(t + '*')
+ gv_p = Var(gv_ptr.type)
self.asm.append(' %s=getelementptr %s,%s %s' % (
- gv_p.operand2(), gv_ptr_var.operand(), i32, offset / fieldsize))
- gv_result = Var(t)
+ gv_p.operand2(), gv_ptr_var.operand(), i32, offset))
+ gv_p2 = self._cast_to(gv_p, fieldtype + '*')
+ gv_result = Var(fieldtype)
self.asm.append(' %s=load %s' % (
- gv_result.operand2(), gv_p.operand()))
+ gv_result.operand2(), gv_p2.operand()))
return gv_result
- def genop_setfield(self, (offset, fieldsize), gv_ptr, gv_value):
- log('%s Builder.genop_setfield (%d,%d) %s=%s' % (
- self.block.label, offset, fieldsize, gv_ptr.operand(), gv_value.operand()))
- #if fieldsize == WORD:
- # gv_result = Var(i32)
- #else:
- # if fieldsize == 1:
- # gv_result = Var(i8)
- # else:
- # assert fieldsize == 2
- # gv_result = Var(i16)
+ def genop_setfield(self, fieldtoken, gv_ptr, gv_value):
+ offset, fieldtype = fieldtoken
+ log('%s Builder.genop_setfield (%d,%s) %s=%s' % (
+ self.block.label, offset, fieldtype, gv_ptr.operand(), gv_value.operand()))
gv_ptr_var = self._as_var(gv_ptr)
- gv_p = Var(gv_value.type+'*')
+ gv_p = Var(gv_ptr.type)
self.asm.append(' %s=getelementptr %s,%s %s' % (
- gv_p.operand2(), gv_ptr_var.operand(), i32, offset / fieldsize))
+ gv_p.operand2(), gv_ptr_var.operand(), i32, offset))
+ gv_p2 = self._cast_to(gv_p, fieldtype + '*')
self.asm.append(' store %s,%s' % (
- gv_value.operand(), gv_p.operand()))
+ gv_value.operand(), gv_p2.operand()))
- def genop_getsubstruct(self, (offset, fieldsize), gv_ptr):
- log('%s Builder.genop_getsubstruct (%d,%d) %s' % (
- self.block.label, offset, fieldsize, gv_ptr.operand()))
+ def genop_getsubstruct(self, fieldtoken, gv_ptr):
+ offset, fieldtype = fieldtoken
+ log('%s Builder.genop_getsubstruct (%d,%s) %s' % (
+ self.block.label, offset, fieldtype, gv_ptr.operand()))
gv_ptr_var = self._as_var(gv_ptr)
gv_sub = Var(gv_ptr.type)
self.asm.append(' %s=getelementptr %s,%d' % (
gv_sub.operand2(), gv_ptr_var.operand(), offset))
return gv_sub
- def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
- array_length_offset, array_items_offset, itemsize = arraytoken
- log('%s Builder.genop_getarrayitem %s,%s,%s' % (
- self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
-
- gv_i = Var(gv_index.type)
- try:
- offset = array_items_offset / itemsize
- except TypeError:
- offset = 4 #XXX (get inspired by ppc backend)
- self.asm.append(' %s=add %s,%d' % (
- gv_i.operand2(), gv_index.operand(), offset)) #/itemsize correct?
-
- gv_ptr_var = self._as_var(gv_ptr)
- gv_p = Var(gv_ptr_var.type)
- self.asm.append(' %s=getelementptr %s,%s' % (
- gv_p.operand2(), gv_ptr_var.operand(), gv_i.operand()))
-
- gv_result = Var(gv_ptr_var.type[:-1])
- self.asm.append(' %s=load %s' % (
- gv_result.operand2(), gv_p.operand()))
- return gv_result
-
def genop_getarraysubstruct(self, arraytoken, gv_ptr, gv_index):
'''
self.mc.MOV(edx, gv_ptr.operand(self))
@@ -751,7 +715,7 @@
return self.returnvar(eax)
'''
#XXX TODO
- array_length_offset, array_items_offset, itemsize = arraytoken
+ array_length_offset, array_items_offset, itemitem = arraytoken
gv_result = Var(i32)
log('%s Builder.genop_getarraysubstruct %s,%s,%s' % (
self.block.label, arraytoken, gv_ptr, gv_index))
@@ -766,7 +730,7 @@
return self.returnvar(mem(edx, lengthoffset))
'''
#XXX TODO
- array_length_offset, array_items_offset, itemsize = arraytoken
+ array_length_offset, array_items_offset, itemtype = arraytoken
gv_result = Var(i32)
log('%s Builder.genop_getarraysize %s,%s' % (
self.block.label, arraytoken, gv_ptr))
@@ -782,31 +746,54 @@
gv_var.operand2(), inttoptr, i32, gv.operand2(), gv_var.type))
return gv_var
return gv
-
+
+ def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
+ array_length_offset, array_items_offset, item_type = arraytoken
+ log('%s Builder.genop_getarrayitem %s,%s[%s]' % (
+ self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
+
+ gv_ptr_var = self._as_var(gv_ptr)
+
+ gv_p = Var(gv_ptr_var.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, array_items_offset))
+
+ gv_p2 = self._cast_to(gv_p, item_type + '*')
+
+ gv_p3 = Var(gv_p2.type)
+ self.asm.append(' %s=getelementptr %s,%s' % (
+ gv_p3.operand2(), gv_p2.operand(), gv_index.operand()))
+
+ gv_result = Var(item_type)
+ self.asm.append(' %s=load %s' % (
+ gv_result.operand2(), gv_p3.operand()))
+
+ return gv_result
+
def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
- array_length_offset, array_items_offset, itemsize = arraytoken
- log('%s Builder.genop_setarrayitem %s,%s,%s,%s' % (
+ array_length_offset, array_items_offset, item_type = arraytoken
+ log('%s Builder.genop_setarrayitem %s,%s[%s]=%s' % (
self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand(), gv_value.operand()))
- try:
- offset = array_items_offset / itemsize
- except TypeError:
- offset = 4 #XXX (get inspired by ppc backend)
- gv_i = Var(gv_index.type)
- self.asm.append(' %s=add %s,%d ;;;;' % (
- gv_i.operand2(), gv_index.operand(), offset)) #/itemsize correct?
-
gv_ptr_var = self._as_var(gv_ptr)
+
gv_p = Var(gv_ptr_var.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, array_items_offset))
+
+ gv_p2 = self._cast_to(gv_p, item_type + '*')
+
+ gv_p3 = Var(gv_p2.type)
self.asm.append(' %s=getelementptr %s,%s' % (
- gv_p.operand2(), gv_ptr_var.operand(), gv_i.operand()))
+ gv_p3.operand2(), gv_p2.operand(), gv_index.operand()))
+
self.asm.append(' store %s,%s' % (
- gv_value.operand(), gv_p.operand()))
+ gv_value.operand(), gv_p3.operand()))
def genop_malloc_fixedsize(self, size):
log('%s Builder.genop_malloc_fixedsize %s' % (
self.block.label, str(size)))
- t = i8 + '*' #XXX or opaque* ?
+ t = pi8
gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
gv_result = Var(t)
#XXX or use addGlobalFunctionMapping in libllvmjit.restart()
@@ -820,7 +807,7 @@
def genop_malloc_varsize(self, varsizealloctoken, gv_size):
log('%s Builder.genop_malloc_varsize %s,%s' % (
self.block.label, varsizealloctoken, gv_size.operand()))
- t = i8 + '*' #XXX or opaque* ?
+ t = pi8
gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
gv_result = Var(t)
#XXX or use addGlobalFunctionMapping in libllvmjit.restart()
@@ -974,18 +961,16 @@
def kindToken(T):
# turn the type T into the llvm approximation that we'll use here
# XXX incomplete
- if isinstance(T, lltype.Ptr):
- return i32 + '*' #or opaque* ?
- elif T is llmemory.Address:
- return i32 + '*' #or apaque* ?
- if T is lltype.Bool:
+ if isinstance(T, lltype.Ptr) or T is llmemory.Address:
+ return pi8
+ elif T is lltype.Bool:
return 'bool'
elif T is lltype.Char:
return i8
elif T is lltype.Unsigned:
- return i32 #'uint'
+ return u32
elif T is lltype.Float:
- return 'float'
+ return f64
else:
return i32 #Signed/UniChar/Void
@@ -994,10 +979,10 @@
def fieldToken(T, name):
FIELD = getattr(T, name)
if isinstance(FIELD, lltype.ContainerType):
- fieldsize = 0 # not useful for getsubstruct
+ fieldtype = pi8 # not useful for getsubstruct
else:
- fieldsize = llmemory.sizeof(FIELD)
- return (llmemory.offsetof(T, name), fieldsize)
+ fieldtype = RLLVMGenOp.kindToken(FIELD)
+ return (llmemory.offsetof(T, name), fieldtype)
@staticmethod
@specialize.memo()
@@ -1015,19 +1000,18 @@
arrayfield = T._arrayfld
ARRAYFIELD = getattr(T, arrayfield)
arraytoken = RLLVMGenOp.arrayToken(ARRAYFIELD)
- length_offset, items_offset, item_size = arraytoken
+ length_offset, items_offset, item_type = arraytoken
arrayfield_offset = llmemory.offsetof(T, arrayfield)
return (arrayfield_offset+length_offset,
arrayfield_offset+items_offset,
- item_size)
+ item_type) #XXX was item_size
@staticmethod
@specialize.memo()
def arrayToken(A):
- #XXX TODO
return (llmemory.ArrayLengthOffset(A),
llmemory.ArrayItemsOffset(A),
- llmemory.ItemOffset(A.OF))
+ RLLVMGenOp.kindToken(A.OF))
@staticmethod
@specialize.memo()
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Thu Jan 11 17:02:01 2007
@@ -70,10 +70,10 @@
test_merge_structures = skip
test_simple_meth = skip
test_simple_red_meth = skip
+ test_degenerated_at_return = skip
#failing...
if skip_failing:
- test_degenerated_at_return = skip
test_degenerate_with_voids = skip
test_red_array = skip
test_red_struct_array = skip
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py Thu Jan 11 17:02:01 2007
@@ -26,6 +26,7 @@
test_float_arithmetic = skip_too_minimal #segfault
test_unsigned = skip_too_minimal #uint_invert uses incorrect xor constant?
+ test_float_cast = skip #works when f64 is 'float' but not when 'double' because of 0.0 compare
test_float_pow = skip
test_unichar_array = skip
test_char_unichar_fields = skip
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py Thu Jan 11 17:02:01 2007
@@ -25,3 +25,5 @@
test_fact_direct = skip_too_minimal #segfault
test_fact_compile = skip #XXX Blocked block, introducted by this checkin (I don't understand)
+ test_calling_pause_direct = skip #segfault, look into later...
+ test_calling_pause_compile = skip # dito
From santagada at codespeak.net Thu Jan 11 17:22:14 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 17:22:14 +0100 (CET)
Subject: [pypy-svn] r36513 - in pypy/dist/pypy/lang/js: . js test
Message-ID: <20070111162214.3BA8610072@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 17:22:10 2007
New Revision: 36513
Modified:
pypy/dist/pypy/lang/js/js/jsparse.js
pypy/dist/pypy/lang/js/js_interactive.py
pypy/dist/pypy/lang/js/jsparser.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
make parsing of files more complete
Modified: pypy/dist/pypy/lang/js/js/jsparse.js
==============================================================================
--- pypy/dist/pypy/lang/js/js/jsparse.js (original)
+++ pypy/dist/pypy/lang/js/js/jsparse.js Thu Jan 11 17:22:10 2007
@@ -272,17 +272,29 @@
return /^\W/.test(t) ? opTypeNames[t] : t.toUpperCase();
}
+function printtarget(target) {
+ return tokenstr(target.type)+","+target.lineno+","+target.start
+}
+
Np.toString = function () {
var a = [];
for (var i in this) {
if (this.hasOwnProperty(i) && i != 'type')
a.push({id: i, value: this[i]});
}
- a.sort(function (a,b) { return (a.id < b.id) ? -1 : 1; });
+ // a.sort(function (a,b) { return (a.id < b.id) ? -1 : 1; });
const INDENTATION = " ";
var n = ++Node.indentLevel;
var s = "{\n" + INDENTATION.repeat(n) + "'type': '" + tokenstr(this.type) + "'";
for (i = 0; i < a.length; i++) {
+ if(a[i].id == 'tokenizer') {
+ continue
+ } else {
+ if(a[i].id == 'target'){
+ s += ",\n" + INDENTATION.repeat(n) + "'target': '" + printtarget(a[i].value) + "' ";
+ continue
+ }
+ }
val = a[i].value + "";
if ((val.search("\\},\\{") != -1 )) {
s += ",\n" + INDENTATION.repeat(n) + "'" + a[i].id + "': [" + val + "]";
@@ -587,7 +599,6 @@
n.end = n.expression.end;
break;
}
-
if (t.lineno == t.token.lineno) {
tt = t.peekOnSameLine();
if (tt != END && tt != NEWLINE && tt != SEMICOLON && tt != RIGHT_CURLY)
Modified: pypy/dist/pypy/lang/js/js_interactive.py
==============================================================================
--- pypy/dist/pypy/lang/js/js_interactive.py (original)
+++ pypy/dist/pypy/lang/js/js_interactive.py Thu Jan 11 17:22:10 2007
@@ -8,10 +8,12 @@
import sys
import getopt
from pypy.lang.js.interpreter import *
-from pypy.lang.js.jsobj import W_Builtin
+from pypy.lang.js.jsobj import W_Builtin, W_String
help_message = '''
-The help message goes here.
+Pypy Javascript Interpreter:
+ -f filname Load a file
+ -h show this help message
'''
@@ -19,24 +21,28 @@
def __init__(self, msg):
self.msg = msg
+def loadjs(ctx, filename):
+ f = open(filename.ToString())
+ t = load_source(f.read())
+ f.close()
+ return t.execute(ctx)
def main(argv=None):
if argv is None:
argv = sys.argv
try:
try:
- opts, args = getopt.getopt(argv[1:], "ho:v", ["help", "output="])
+ opts, args = getopt.getopt(argv[1:], "hf:", ["help",])
except getopt.error, msg:
raise Usage(msg)
# option processing
+ filenames = []
for option, value in opts:
- if option == "-v":
- verbose = True
+ if option == "-f":
+ filenames.append(value)
if option in ("-h", "--help"):
raise Usage(help_message)
- if option in ("-o", "--output"):
- output = value
except Usage, err:
print >> sys.stderr, sys.argv[0].split("/")[-1] + ": " + str(err.msg)
@@ -49,9 +55,12 @@
return "this should not be printed"
interp.w_Global.Put('quit', W_Builtin(quiter))
+ interp.w_Global.Put('load', W_Builtin(loadjs, context=True, args=1))
+ for filename in filenames:
+ loadjs(interp.global_context, W_String(filename))
while 1:
- res = interp.run(load_source(raw_input("pypy-js>")))
+ res = interp.run(load_source(raw_input("pypy-js> ")))
if res is not None:
print res
Modified: pypy/dist/pypy/lang/js/jsparser.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsparser.py (original)
+++ pypy/dist/pypy/lang/js/jsparser.py Thu Jan 11 17:22:10 2007
@@ -15,18 +15,19 @@
pass
def read_js_output(code_string):
- stripped_code = code_string.replace("\n", "")
+ stripped_code = code_string.replace("\n", "\\n")
+ stripped_code = stripped_code.replace("'",r"\'")
jsdir = py.path.local(__file__).dirpath().join("js")
jsdefs = jsdir.join("jsdefs.js").read()
jsparse = jsdir.join("jsparse.js").read()
- pipe = Popen("js", stdin=PIPE, stdout=PIPE, stderr=STDOUT)
- pipe.stdin.write(jsdefs + jsparse + "\n")
- stripped_code = stripped_code.replace("'",r"\'")
- pipe.stdin.write("print(parse('%s'));\n" % stripped_code)
- pipe.stdin.close()
- retval = pipe.stdout.read()
+ f = open('/tmp/jstobeparsed.js','w')
+ f.write(jsdefs)
+ f.write(jsparse)
+ f.write("print(parse('%s'));\n" % stripped_code)
+ f.close()
+ pipe = os.popen("js -f /tmp/jstobeparsed.js", 'r')
+ retval = pipe.read()
if not retval.startswith("{"):
- print stripped_code
raise JsSyntaxError(retval)
return retval
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 17:22:10 2007
@@ -313,6 +313,11 @@
print(z);
""", ["3","2"])
+ def test_load(self):
+ py.test.skip("not ready yet")
+ self.assert_prints("""
+ load("simple.js")
+ """, ["3","2"])
From fijal at codespeak.net Thu Jan 11 17:22:27 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Thu, 11 Jan 2007 17:22:27 +0100 (CET)
Subject: [pypy-svn] r36514 - in pypy/dist/pypy/annotation: . test
Message-ID: <20070111162227.813A010077@code0.codespeak.net>
Author: fijal
Date: Thu Jan 11 17:22:23 2007
New Revision: 36514
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
Add a possibility to select a callback
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Thu Jan 11 17:22:23 2007
@@ -19,6 +19,7 @@
from pypy.annotation.model import read_can_only_throw
from pypy.annotation.model import add_knowntypedata, merge_knowntypedata
from pypy.annotation.model import lltype_to_annotation
+from pypy.annotation.model import SomeGenericCallable
from pypy.annotation.bookkeeper import getbookkeeper
from pypy.objspace.flow.model import Variable
from pypy.annotation.listdef import ListDef
@@ -682,6 +683,12 @@
s.const = False # no common desc in the two sets
return s
+class __extend__(pairtype(SomeGenericCallable, SomePBC)):
+ def union((gencall, pbc)):
+ unique_key = (gencall, pbc.const)
+ getbookkeeper().emulate_pbc_call(unique_key, pbc, gencall.args_s)
+ return gencall
+
class __extend__(pairtype(SomeImpossibleValue, SomeObject)):
def union((imp1, obj2)):
return obj2
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Thu Jan 11 17:22:23 2007
@@ -2464,12 +2464,12 @@
assert not hasattr(s, 'const')
def test_some_generic_function_callback(self):
- py.test.skip("Not implemented")
def g(a):
pass
g._known_annotation_ = annmodel.SomeGenericCallable(
- args=[annmodel.SomeGenericCallable(args=[SomeInteger()],
- retval=SomeInteger())])
+ args=[annmodel.SomeGenericCallable(args=[annmodel.SomeInteger()],
+ retval=annmodel.SomeInteger())],
+ retval=annmodel.SomeInteger())
def fun2(x):
return x
@@ -2478,8 +2478,17 @@
return g(fun2)
a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
- s = a.build_types(func, [])
- # assert that annotator knows about fun2 and is flown well
+ s = a.build_types(fun, [])
+ assert isinstance(s, annmodel.SomeInteger)
+ graphs = a.annotated.values()
+ found = False
+ for graph in graphs:
+ if graph.name == "fun2":
+ found = True
+ inputcells = graph.startblock.inputargs
+ assert len(inputcells) == 1
+ assert isinstance(a.bindings[inputcells[0]], annmodel.SomeInteger)
+ assert found
def g(n):
return [0,1,2,n]
From santagada at codespeak.net Thu Jan 11 17:57:13 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 17:57:13 +0100 (CET)
Subject: [pypy-svn] r36515 - pypy/dist/pypy/lang/js/test
Message-ID: <20070111165713.E5D7410068@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 17:57:13 2007
New Revision: 36515
Modified:
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
defined the tests wich passing permits testing with the mozilla test suite directly
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 17:57:13 2007
@@ -151,7 +151,7 @@
""", ["test"])
def test_array_initializer(self):
- py.test.skip("not ready yet")
+ py.test.skip(" TODO: needed for mozilla test suite")
self.assert_prints("""
x = [];
print(x);
@@ -319,5 +319,45 @@
load("simple.js")
""", ["3","2"])
-
-
+ def test_arrayobject(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+ x= """var testcases = new Array();
+ var tc = testcases.length;"""
+
+ def test_break(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+
+ def test_typeof(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+
+ def test_switch(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+
+ def test_newwithargs(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+
+ def test_increment(self):
+ x = "x++"
+ py.test.skip(" TODO: needed for mozilla test suite")
+
+ def test_ternaryop(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+ x = " ( t < 0 ) ? -1 : 1;"
+
+ def test_smallthings(self):
+ py.test.skip(" TODO: needed for mozilla test suite")
+ x = """
+ var x;
+ if ( gc == undefined ) {
+ print('undef');
+ }
+ """
+ x = "if ( ! x ) { "
+ x = "var x = false;"
+
+ x = "Math.abs(actual-expect) < 0.0000001 ) {"
+ x = """if ( isNaN( t ) ){
+ return ( Number.NaN );"""
+ x = "Number.POSITIVE_INFINITY Number.NEGATIVE_INFINITY"
+ x = "Math.floor( Math.abs( t ) ) );"
+ x = "this.orig.werror = this.werror = false;"
\ No newline at end of file
From santagada at codespeak.net Thu Jan 11 18:08:11 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 18:08:11 +0100 (CET)
Subject: [pypy-svn] r36516 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070111170811.5D3ED10072@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 18:08:10 2007
New Revision: 36516
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
increment implemented
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Thu Jan 11 18:08:10 2007
@@ -300,8 +300,8 @@
thing = self.op.eval(ctx)
val = thing.GetValue()
x = val.ToNumber()
- resl = Plus(W_Number(x), W_Number(1)).eval(ctx).GetValue()
- thing.PutValue(resl)
+ resl = Plus(None, None).decision(ctx, W_Number(x), W_Number(1))
+ thing.PutValue(resl, ctx)
return resl
class Index(Expression):
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 18:08:10 2007
@@ -337,8 +337,11 @@
py.test.skip(" TODO: needed for mozilla test suite")
def test_increment(self):
- x = "x++"
- py.test.skip(" TODO: needed for mozilla test suite")
+ self.assert_prints("""
+ var x;
+ x = 1
+ x++
+ print(x)""", ["2"])
def test_ternaryop(self):
py.test.skip(" TODO: needed for mozilla test suite")
From santagada at codespeak.net Thu Jan 11 18:09:19 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 18:09:19 +0100 (CET)
Subject: [pypy-svn] r36517 - pypy/dist/pypy/lang/js/test
Message-ID: <20070111170919.B74F710074@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 18:09:15 2007
New Revision: 36517
Modified:
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
no one do i=i+1 in a for loop :)
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 18:09:15 2007
@@ -300,7 +300,7 @@
def test_for(self):
self.assert_prints("""
- for (i=0; i<3; i=i+1) {
+ for (i=0; i<3; i++) {
print(i);
}
print(i);
From niko at codespeak.net Thu Jan 11 18:15:13 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 18:15:13 +0100 (CET)
Subject: [pypy-svn] r36518 - in pypy/dist/pypy/translator: cli jvm jvm/src
jvm/src/pypy jvm/test oosupport oosupport/test_template
Message-ID: <20070111171513.51B5310072@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 18:15:11 2007
New Revision: 36518
Added:
pypy/dist/pypy/translator/jvm/src/pypy/
pypy/dist/pypy/translator/jvm/src/pypy/DictItemsIterator.java
pypy/dist/pypy/translator/jvm/src/pypy/ExceptionWrapper.java
pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
pypy/dist/pypy/translator/jvm/test/test_dict.py
pypy/dist/pypy/translator/oosupport/test_template/dict.py
Removed:
pypy/dist/pypy/translator/jvm/src/ExceptionWrapper.java
pypy/dist/pypy/translator/jvm/src/PyPy.java
Modified:
pypy/dist/pypy/translator/cli/class_.py
pypy/dist/pypy/translator/cli/function.py
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/genjvm.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/test/runtest.py
pypy/dist/pypy/translator/jvm/typesystem.py
pypy/dist/pypy/translator/oosupport/constant.py
pypy/dist/pypy/translator/oosupport/genoo.py
Log:
(antocuni, niko)
fix a number of errors from test_dict
Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py (original)
+++ pypy/dist/pypy/translator/cli/class_.py Thu Jan 11 18:15:11 2007
@@ -132,6 +132,7 @@
f_name = self.cts.escape_name(f_name)
if cts_type != 'void':
self.ilasm.opcode('ldarg.0')
+ print "%s f_default=%s" % (self.name, f_default)
push_constant(self.db, F_TYPE, f_default, self.gen)
class_name = self.db.class_name(self.INSTANCE)
self.ilasm.set_field((cts_type, class_name, f_name))
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Thu Jan 11 18:15:11 2007
@@ -17,7 +17,7 @@
from pypy.translator.cli.support import log
from pypy.translator.cli.ilgenerator import CLIBaseGenerator
-USE_LAST = True
+USE_LAST = False
class NativeExceptionHandler(object):
def begin_try(self):
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Thu Jan 11 18:15:11 2007
@@ -3,7 +3,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.typesystem import \
jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject, \
- jBool
+ jBool, jHashMap, jPyPyDictItemsIterator, Generifier
# ______________________________________________________________________
# Mapping of built-in OOTypes to JVM types
@@ -19,20 +19,9 @@
def __init__(self, db, classty, OOTYPE):
jvmtype.JvmClassType.__init__(self, classty.name)
self.db = db
- self.OOTYPE = OOTYPE # might be None
+ self.OOTYPE = OOTYPE
+ self.gen = Generifier(OOTYPE)
- # We need to create a mapping for any generic parameters this
- # OOTYPE may have. Other than SELFTYPE_T, we map each generic
- # argument to ootype.ROOT. We use a hack here where we assume
- # that the only generic parameters are named SELFTYPE_T,
- # ITEMTYPE_T, KEYTYPE_T, or VALUETYPE_T.
- self.generics = {}
- if hasattr(self.OOTYPE, 'SELFTYPE_T'):
- self.generics[self.OOTYPE.SELFTYPE_T] = self.OOTYPE
- for param in ('ITEMTYPE_T', 'KEYTYPE_T', 'VALUETYPE_T'):
- if hasattr(self.OOTYPE, param):
- self.generics[getattr(self.OOTYPE, param)] = ootype.ROOT
-
def __eq__(self, other):
return isinstance(other, JvmBuiltInType) and other.name == self.name
@@ -46,16 +35,10 @@
return jvmgen.Field(
self.descriptor.class_name(), fieldnm, jfieldty, False)
- def _map(self, ARG):
- """ Maps ootype ARG to a java type. If arg is one of our
- generic arguments, substitutes the appropriate type before
- performing the mapping. """
- return self.db.lltype_to_cts(self.generics.get(ARG,ARG))
-
def lookup_method(self, methodnm):
""" Given the method name, returns a jvmgen.Method object """
- # Look for a shortcut method
+ # Look for a shortcut method in our table of remappings:
try:
key = (self.OOTYPE.__class__, methodnm)
print "key=%r" % (key,)
@@ -63,20 +46,33 @@
return built_in_methods[key]
except KeyError: pass
- # Lookup the generic method by name.
- GENMETH = self.OOTYPE._GENERIC_METHODS[methodnm]
-
- # By default, we assume it is a static method on the PyPy
- # object, that takes an instance of this object as the first
- # argument. The other arguments we just convert to java versions,
- # except for generics.
- jargtypes = [self] + [self._map(P) for P in GENMETH.ARGS]
- jrettype = self._map(GENMETH.RESULT)
- return jvmgen.Method.s(jPyPy, methodnm, jargtypes, jrettype)
-
-# When we lookup a method on a BuiltInClassNode, we first check
-# the 'built_in_methods' table. This allows us to redirect to other
-# methods if we like.
+ # Otherwise, determine the Method object automagically
+ # First, map the OOTYPE arguments and results to
+ # the java types they will be at runtime. Note that
+ # we must use the erased types for this.
+ ARGS, RESULT = self.gen.erased_types(methodnm)
+ jargtypes = [self.db.lltype_to_cts(P) for P in ARGS]
+ jrettype = self.db.lltype_to_cts(RESULT)
+
+ if self.OOTYPE.__class__ in bridged_objects:
+ # Bridged objects are ones where we have written a java class
+ # that has methods with the correct names and types already
+ return jvmgen.Method.v(self, methodnm, jargtypes, jrettype)
+ else:
+ # By default, we assume it is a static method on the PyPy
+ # object, that takes an instance of this object as the first
+ # argument. The other arguments we just convert to java versions,
+ # except for generics.
+ jargtypes = [self] + jargtypes
+ return jvmgen.Method.s(jPyPy, methodnm, jargtypes, jrettype)
+
+# When we lookup a method on a BuiltInClassNode, we first check the
+# 'built_in_methods' and 'bridged_objects' tables. This allows us to
+# redirect to other methods if we like.
+
+bridged_objects = (
+ ootype.DictItemsIterator,
+ )
built_in_methods = {
@@ -94,6 +90,24 @@
(ootype.String.__class__, "ll_strlen"):
jvmgen.Method.v(jString, "length", (), jInt),
+
+ (ootype.String.__class__, "ll_stritem_nonneg"):
+ jvmgen.Method.v(jString, "charAt", (jInt,), jChar),
+
+ (ootype.Dict, "ll_set"):
+ jvmgen.Method.v(jHashMap, "put", (jObject, jObject), jObject),
+
+ (ootype.Dict, "ll_get"):
+ jvmgen.Method.v(jHashMap, "get", (jObject,), jObject),
+
+ (ootype.Dict, "ll_contains"):
+ jvmgen.Method.v(jHashMap, "containsKey", (jObject,), jBool),
+
+ (ootype.Dict, "ll_length"):
+ jvmgen.Method.v(jHashMap, "size", (), jInt),
+
+ (ootype.Dict, "ll_clear"):
+ jvmgen.Method.v(jHashMap, "clear", (), jVoid),
(ootype.List, "ll_length"):
jvmgen.Method.v(jArrayList, "size", (), jInt),
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Thu Jan 11 18:15:11 2007
@@ -293,7 +293,7 @@
ootype.UnsignedLongLong: jvmtype.jLong,
ootype.Bool: jvmtype.jBool,
ootype.Float: jvmtype.jDouble,
- ootype.Char: jvmtype.jByte,
+ ootype.Char: jvmtype.jChar, # byte would be sufficient, but harder
ootype.UniChar: jvmtype.jChar,
ootype.Class: jvmtype.jClass,
ootype.ROOT: jvmtype.jObject, # count this as a scalar...
@@ -304,7 +304,9 @@
ootype_to_builtin = {
ootype.String: jvmtype.jString,
ootype.StringBuilder: jvmtype.jStringBuilder,
- ootype.List: jvmtype.jArrayList
+ ootype.List: jvmtype.jArrayList,
+ ootype.Dict: jvmtype.jHashMap,
+ ootype.DictItemsIterator:jvmtype.jPyPyDictItemsIterator,
}
def lltype_to_cts(self, OOT):
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 18:15:11 2007
@@ -851,6 +851,16 @@
mthd = clsobj.lookup_method(method_name)
mthd.invoke(self)
+ # Check if we have to convert the result type at all:
+ gener = jvmtype.Generifier(OOCLASS)
+ RETTYPE = gener.full_types(method_name)[1]
+ jrettype = self.db.lltype_to_cts(RETTYPE)
+ if jrettype != mthd.return_type:
+ # if the intended return type is not the same as the
+ # actual return type in the JVM (mthd.return_type),
+ # we have to "deal with it"
+ self.prepare_generic_result(RETTYPE)
+
def call_primitive(self, graph):
raise NotImplementedError
Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py (original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py Thu Jan 11 18:15:11 2007
@@ -95,17 +95,22 @@
raise JvmSubprogramError(res, args, stdout, stderr)
return stdout, stderr
- def _compile_helper(self, clsnm):
+ def _compile_helper(self, clsnms):
# HACK: compile the Java helper class. Should eventually
# use rte.py
- pypycls = self.classdir.join(clsnm + '.class')
- if not os.path.exists(str(pypycls)):
+ tocompile = []
+ for clsnm in clsnms:
+ pypycls = self.classdir.join(clsnm + '.class')
+ if not os.path.exists(str(pypycls)):
+ tocompile.append(clsnm)
+ if tocompile:
sl = __file__.rindex('/')
- javasrc = __file__[:sl]+("/src/%s.java" % clsnm)
+ javasrcs = [__file__[:sl]+("/src/pypy/%s.java" % clsnm) for
+ clsnm in tocompile]
self._invoke([getoption('javac'),
'-nowarn',
- '-d', str(self.classdir),
- javasrc],
+ '-d', str(self.classdir)]+
+ javasrcs,
True)
@@ -119,8 +124,9 @@
self._invoke(jascmd+list(self.jasmin_files), False)
self.compiled = True
- self._compile_helper('PyPy')
- self._compile_helper('ExceptionWrapper')
+ self._compile_helper(('DictItemsIterator',
+ 'PyPy',
+ 'ExceptionWrapper'))
def execute(self, args):
"""
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 18:15:11 2007
@@ -367,7 +367,7 @@
""" Represents a class to be emitted. Note that currently, classes
are emitted all in one shot, not piecemeal. """
- def __init__(self, name, supercls=None):
+ def __init__(self, name, supercls=None, initialize_fields=True):
"""
'name' should be a fully qualified Java class name like
"java.lang.String", supercls is a Class object
@@ -435,6 +435,8 @@
if field.jtype is not jVoid:
gen.load_jvm_var(self, 0) # load this ptr
# load default value of field
+ print "%s f_name=%s f_default=%s" % (
+ self.name, field.field_name, f_default)
push_constant(gen.db, field.OOTYPE, f_default, gen)
field.store(gen) # store value into field
gen.end_constructor()
@@ -495,24 +497,21 @@
# Start the dump
genprint("InstanceWrapper(")
genprint("'" + self.OOCLASS._name + "', ")
- genprint("[")
+ genprint("{")
for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
if FIELDOOTY is ootype.Void: continue
- genprint("(")
- genprint('"'+fieldnm+'",')
+ genprint('"'+fieldnm+'":')
print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
# Print the value of the field:
self._print_field_value(fieldnm, FIELDOOTY)
- genprint(")")
-
# Dump close
- genprint("])")
+ genprint("})")
class RecordDumpMethod(BaseDumpMethod):
Added: pypy/dist/pypy/translator/jvm/src/pypy/DictItemsIterator.java
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/src/pypy/DictItemsIterator.java Thu Jan 11 18:15:11 2007
@@ -0,0 +1,29 @@
+package pypy;
+
+import java.util.Map;
+import java.util.Iterator;
+
+public class DictItemsIterator
+{
+ private Iterator iterator;
+ private Map.Entry current;
+
+ public DictItemsIterator(Map map) {
+ this.iterator = map.entrySet().iterator();
+ }
+
+ public boolean ll_go_next() {
+ if (!this.iterator.hasNext())
+ return false;
+ this.current = this.iterator.next();
+ return true;
+ }
+
+ public Object ll_current_key() {
+ return this.current.getKey();
+ }
+
+ public Object ll_current_value() {
+ return this.current.getValue();
+ }
+}
\ No newline at end of file
Added: pypy/dist/pypy/translator/jvm/src/pypy/ExceptionWrapper.java
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/src/pypy/ExceptionWrapper.java Thu Jan 11 18:15:11 2007
@@ -0,0 +1,13 @@
+package pypy;
+
+public class ExceptionWrapper extends RuntimeException {
+ public final Object object;
+
+ ExceptionWrapper (Object object) {
+ this.object = object;
+ }
+
+ public static ExceptionWrapper wrap(Object object) {
+ return new ExceptionWrapper(object);
+ }
+}
\ No newline at end of file
Added: pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java Thu Jan 11 18:15:11 2007
@@ -0,0 +1,475 @@
+package pypy;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+/**
+ * Class with a number of utility routines.
+ *
+ * I apologize for the Python-esque naming conventions, but it seems
+ * I can't switch my mind to camelCase when working so closely with
+ * Python mere minutes before.
+ */
+public class PyPy {
+ /**
+ * Compares two unsigned integers (value1 and value2) and returns
+ * a value greater than, equal to, or less than zero if value 1 is
+ * respectively greater than, equal to, or less than value2. The
+ * idea is that you can do the following:
+ *
+ * Call uint_cmp(value1, value2)
+ * IFLT ... // jumps if value1 < value2
+ * IFEQ ... // jumps if value1 == value2
+ * IFGT ... // jumps if value1 > value2
+ * etc
+ */
+ public static int uint_cmp(int value1, int value2) {
+ final int VALUE1BIGGER = 1;
+ final int VALUE2BIGGER = -1;
+ final int EQUAL = 0;
+
+ if (((value1 | value2) & Integer.MIN_VALUE) == 0) {
+ // neither is negative, presumably the common case
+ return value1 - value2;
+ }
+
+ if (value1 == value2)
+ return EQUAL;
+
+ if (value1 < 0) {
+ if (value2 < 0) {
+ // both are negative
+ if (value1 > value2)
+ // example: value1 == -1 (0xFFFF), value2 == -2 (0xFFFE)
+ return VALUE1BIGGER;
+ return VALUE2BIGGER;
+ }
+ else {
+ // value1 is neg, value 2 is not
+ return VALUE1BIGGER;
+ }
+ }
+
+ // value1 is not neg, value2 is neg
+ return VALUE2BIGGER;
+ }
+
+ public static int ulong_cmp(long value1, long value2) {
+ final int VALUE2BIGGER = -1;
+ final int VALUE1BIGGER = 1;
+ final int EQUAL = 0;
+
+ if (value1 == value2)
+ return EQUAL;
+
+ if (value1 < 0) {
+ if (value2 < 0) {
+ // both are negative
+ if (value1 > value2)
+ // example: value1 == -1 (0xFFFF), value2 == -2 (0xFFFE)
+ return VALUE1BIGGER;
+ return VALUE2BIGGER;
+ }
+ else {
+ // value1 is neg, value 2 is not
+ return VALUE1BIGGER;
+ }
+ }
+ else if (value2 < 0) {
+ // value1 is not neg, value2 is neg
+ return VALUE2BIGGER;
+ }
+
+ if (value1 > value2)
+ return VALUE1BIGGER;
+ return VALUE2BIGGER;
+ }
+
+ public static final double BITS16 = (double)0xFFFF;
+
+ public static double uint_to_double(int value) {
+ if (value >= 0)
+ return value;
+ else {
+ int loword = value & 0xFFFF;
+ double result = loword;
+ int hiword = value >>> 16;
+ result += hiword * BITS16;
+ return result;
+ }
+ }
+
+ public static int double_to_uint(double value) {
+ if (value <= Integer.MAX_VALUE)
+ return (int)value;
+
+ int loword = (int)(value % BITS16);
+ int hiword = (int)(Math.floor(value / BITS16));
+ assert (loword & 0xFFFF0000) == 0;
+ assert (hiword & 0xFFFF0000) == 0;
+ return (hiword << 16) + loword;
+ }
+
+ public static long long_bitwise_negate(long value) {
+ return ~value;
+ }
+
+ public static List> array_to_list(Object[] array) {
+ List l = new ArrayList();
+ for (Object o : array) {
+ l.add(o);
+ }
+ return l;
+ }
+
+ public static int str_to_int(String s) {
+ try {
+ return Integer.parseInt(s);
+ } catch (NumberFormatException fe) {
+ throw new RuntimeException(fe);
+ }
+ }
+
+ public static int str_to_uint(String s) {
+ try {
+ long l = Long.parseLong(s);
+ if (l < Integer.MAX_VALUE)
+ return (int)l;
+ int lowerword = (int)(l & 0xFFFF);
+ int upperword = (int)(l >> 16);
+ return lowerword + (upperword << 16);
+ } catch (NumberFormatException fe) {
+ throw new RuntimeException(fe);
+ }
+ }
+
+ public static long str_to_long(String s) {
+ try {
+ return Long.parseLong(s);
+ } catch (NumberFormatException fe) {
+ throw new RuntimeException(fe);
+ }
+ }
+
+ public static long str_to_ulong(String s) {
+ // oh bother
+ throw new RuntimeException("TODO--- str to ulong");
+ }
+
+ public static boolean str_to_bool(String s) {
+ // not sure what are considered valid boolean values...
+ // let's be very accepting and take both strings and numbers
+ if (s.equalsIgnoreCase("true"))
+ return true;
+ if (s.equalsIgnoreCase("false"))
+ return false;
+
+ try {
+ int i = Integer.parseInt(s);
+ return i != 0;
+ } catch (NumberFormatException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static double str_to_double(String s) {
+ try {
+ return Double.parseDouble(s);
+ } catch (NumberFormatException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ public static char str_to_char(String s) {
+ if (s.length() != 1)
+ throw new RuntimeException("String not single character: '"+s+"'");
+ return s.charAt(0);
+ }
+
+ // Used in testing:
+
+ public static void dump(String text) {
+ System.out.println(text);
+ }
+
+ public static String serialize_void() {
+ return "None";
+ }
+
+ public static String serialize_uint(int i) {
+ if (i >= 0)
+ return Integer.toString(i);
+ else {
+ int loword = i & 0xFFFF;
+ int hiword = i >>> 16;
+ long res = loword + (hiword*0xFFFF);
+ return Long.toString(res);
+ }
+ }
+
+ public static String serialize_boolean(boolean l) {
+ if (l)
+ return "True";
+ else
+ return "False";
+ }
+
+ public static void _append_char(StringBuffer sb, char c) {
+ if (c == '"')
+ sb.append("\\\"");
+ else
+ sb.append(c);
+ }
+
+ public static String escaped_char(char c) {
+ StringBuffer sb = new StringBuffer();
+ sb.append('"');
+ _append_char(sb, c);
+ sb.append('"');
+ return sb.toString();
+ }
+
+ public static String escaped_string(String b) {
+ if (b == null)
+ return "None";
+ StringBuffer sb = new StringBuffer();
+ sb.append('"');
+ for (int i = 0; i < b.length(); i++) {
+ char c = b.charAt(i);
+ _append_char(sb, c);
+ }
+ sb.append('"');
+ return sb.toString();
+ }
+
+ // used in running unit tests
+ // not really part of the dump_XXX set of objects, hence the lack
+ // of an indent parameter
+ public static void dump_exc_wrapper(Object o) {
+ String clnm = o.getClass().getName();
+ StringBuffer sb = new StringBuffer();
+ sb.append("ExceptionWrapper(");
+ sb.append(escaped_string(clnm));
+ sb.append(")");
+ dump(sb.toString());
+ }
+
+ public static String serializeObject(Object o) {
+ if (o == null)
+ return "None";
+ return o.toString();
+ }
+
+ // ----------------------------------------------------------------------
+ // String
+
+ public static String ll_strconcat(String str1, String str2) {
+ return str1 + str2;
+ }
+
+ // ----------------------------------------------------------------------
+ // StringBuffer
+
+ public static void ll_append_char(StringBuilder sb, byte c) {
+ // annoyingly, the actual return code is StringBuilder, so I have
+ // to make this wrapper to ignore the return value
+ sb.append((char)c);
+ }
+
+ public static void ll_append_char(StringBuilder sb, char c) {
+ // annoyingly, the actual return code is StringBuilder, so I have
+ // to make this wrapper to ignore the return value
+ sb.append(c);
+ }
+
+ public static void ll_append(StringBuilder sb, String s) {
+ // annoyingly, the actual return code is StringBuilder, so I have
+ // to make this wrapper to ignore the return value
+ sb.append(s);
+ }
+
+ public static void ll_append(StringBuilder sb, byte[] s) {
+ // This is only used when we are using byte arrays instead of
+ // strings. We should really replace StringBuilder with some
+ // kind of ByteBuilder in that case...
+ for (byte b : s) {
+ sb.append((char)b);
+ }
+ }
+
+ public static byte[] ll_build(StringBuilder sb) {
+ // This is only used when we are using byte arrays instead of
+ // strings. We should really replace StringBuilder with some
+ // kind of ByteBuilder in that case...
+ return string2bytes(sb.toString());
+ }
+
+ // ----------------------------------------------------------------------
+ // Type Manipulation Routines
+
+ public static Object RuntimeNew(Class c) {
+ // all classes in our system have constructors w/ no arguments
+ try {
+ return c.getConstructor().newInstance();
+ } catch (Exception exc) {
+ throw new RuntimeException("Unexpected", exc);
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Helpers
+
+ public static byte[] string2bytes(String s) {
+ return s.getBytes();
+ }
+
+ public static void append(StringBuilder sb, String s) {
+ // avoid the annoying return value of StringBuilder.append
+ sb.append(s);
+ }
+
+ // ----------------------------------------------------------------------
+ // OOString support
+
+ public static String oostring(int n, int base_) {
+ // XXX needs special case for unsigned ints
+ if (base_ == -1)
+ base_ = 10;
+ if (n < 0 && base_ != 10)
+ return "-" + Integer.toString(-n, base_);
+ else
+ return Integer.toString(n, base_);
+ }
+
+ public static String oostring(double d, int base_) {
+ return new Double(d).toString();
+ }
+
+ public static String oostring(Object obj, int base_)
+ {
+ String clnm = obj.getClass().getName();
+ int underscore = clnm.lastIndexOf('_');
+ // strip "pypy." from the start, and _NN from the end
+ clnm = clnm.substring(5, underscore);
+ return String.format("<%s object>", new Object[] { clnm });
+ }
+
+ public static String oostring(char ch, int base_)
+ {
+ return new Character(ch).toString();
+ }
+
+ public static byte[] oostring(byte[] s, int base_)
+ {
+ return s;
+ }
+
+ public static String oostring(String s, int base_)
+ {
+ return s;
+ }
+
+ public static String oostring(boolean b, int base_)
+ {
+ if (b) return "True";
+ return "False";
+ }
+
+ // ----------------------------------------------------------------------
+ // Exceptions
+ //
+ // If we don't use true Java exceptions, then this
+
+/*
+ static private ThreadLocal excObject = new ThreadLocal();
+
+ public static int startTry() {
+ return excCounter.get();
+ }
+
+ public void throw(Object o) {
+ excObject.put(o);
+ }
+
+ public static Object catch(int ctr) {
+ return excObject.get();
+ }
+*/
+
+ // ----------------------------------------------------------------------
+ // Dicts
+
+ public static boolean ll_remove(HashMap map, Object key) {
+ return map.remove(key) != null;
+ }
+
+ public static DictItemsIterator ll_get_items_iterator(HashMap map) {
+ return new DictItemsIterator(map);
+ }
+
+ // ----------------------------------------------------------------------
+ // Lists
+
+ public static void ll_setitem_fast(ArrayList self, int index, Object val)
+ {
+ // need a wrapper because set returns the old value
+ self.set(index, val);
+ }
+
+ public static void _ll_resize_ge(ArrayList self, int length) {
+ while (self.size() < length) {
+ self.add(null);
+ }
+ }
+
+ public static void _ll_resize_le(ArrayList self, int length) {
+ while (self.size() > length) {
+ self.remove(self.size()-1);
+ }
+ }
+
+ public static void _ll_resize(ArrayList self, int length) {
+ if (length > self.size())
+ _ll_resize_ge(self, length);
+ else if (length < self.size())
+ _ll_resize_le(self, length);
+ }
+
+ // ----------------------------------------------------------------------
+ // Self Test
+
+ public static int __counter = 0, __failures = 0;
+ public static void ensure(boolean f) {
+ if (f) {
+ System.out.println("Test #"+__counter+": OK");
+ }
+ else {
+ System.out.println("Test #"+__counter+": FAILED");
+ __failures++;
+ }
+ __counter++;
+ }
+
+ public static void main(String args[]) {
+ // Small self test:
+
+ ensure(uint_cmp(0xFFFFFFFF, 0) > 0);
+ ensure(uint_cmp(0, 0xFFFFFFFF) < 0);
+ ensure(uint_cmp(0x80000000, 0) > 0);
+ ensure(uint_cmp(0, 0x80000000) < 0);
+ ensure(uint_cmp(0xFFFF, 0) > 0);
+ ensure(uint_cmp(0, 0xFFFF) < 0);
+ ensure(uint_cmp(0xFFFFFFFF, 0xFFFF) > 0);
+ ensure(uint_cmp(0xFFFF, 0xFFFFFFFF) < 0);
+
+ ensure(ulong_cmp(0xFFFFFFFFFFFFFFFFL, 0) > 0);
+ ensure(ulong_cmp(0, 0xFFFFFFFFFFFFFFFFL) < 0);
+ ensure(ulong_cmp(0xFFFFFFFFFFFFFFFFL, 0xFFFF) > 0);
+ ensure(ulong_cmp(0xFFFF, 0xFFFFFFFFFFFFFFFFL) < 0);
+ ensure(ulong_cmp(0x8000000000000000L, 0xFFFF) > 0);
+ ensure(ulong_cmp(0xFFFF, 0x8000000000000000L) < 0);
+
+ System.out.println("Total Failures: "+__failures);
+ }
+}
\ No newline at end of file
Modified: pypy/dist/pypy/translator/jvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/runtest.py (original)
+++ pypy/dist/pypy/translator/jvm/test/runtest.py Thu Jan 11 18:15:11 2007
@@ -138,4 +138,7 @@
return isinstance(val, InstanceWrapper)
def read_attr(self, obj, name):
- py.test.skip('read_attr not supported on genjvm tests')
+ py.test.skip("read_attr not supported on JVM")
+ # TODO --- this "almost works": I think the problem is that our
+ # dump methods don't dump fields of the super class??
+ #return obj.fields["o"+name]
Added: pypy/dist/pypy/translator/jvm/test/test_dict.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/test/test_dict.py Thu Jan 11 18:15:11 2007
@@ -0,0 +1,13 @@
+from pypy.translator.jvm.test.runtest import JvmTest
+import pypy.translator.oosupport.test_template.dict as oodict
+
+class TestJvmDict(JvmTest, oodict.BaseTestDict):
+ pass
+
+class TestJvmEmptyDict(JvmTest, oodict.BaseTestEmptyDict):
+ pass
+
+class TestJvmConstantDict(JvmTest, oodict.BaseTestConstantDict):
+ pass
+
+
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Thu Jan 11 18:15:11 2007
@@ -165,6 +165,7 @@
jPyPyExcWrap = JvmClassType('pypy.ExceptionWrapper')
jPyPyConst = JvmClassType('pypy.Constant')
jPyPyMain = JvmClassType('pypy.Main')
+jPyPyDictItemsIterator = JvmClassType('pypy.DictItemsIterator')
class JvmScalarType(JvmType):
"""
@@ -202,4 +203,60 @@
jObjectArray = JvmArrayType(jObject)
jStringArray = JvmArrayType(jString)
+class Generifier(object):
+ """
+
+ A utility class for working with generic methods in the OOTYPE
+ system. You instantiate it with a given type, and you can ask it
+ for the actual or erased types of any method of that type.
+
+ """
+
+ def __init__(self, OOTYPE):
+ self.OOTYPE = OOTYPE
+
+ # Make a hashtable mapping the generic parameter to a tuple:
+ # (actual type, erased type)
+
+ self.generics = {}
+
+ if hasattr(self.OOTYPE, 'SELFTYPE_T'):
+ self.generics[self.OOTYPE.SELFTYPE_T] = (self.OOTYPE,self.OOTYPE)
+
+ for pname,pval in (('ITEMTYPE_T', '_ITEMTYPE'),
+ ('KEYTYPE_T', '_KEYTYPE'),
+ ('VALUETYPE_T', '_VALUETYPE')):
+ if hasattr(self.OOTYPE, pname):
+ placeholder = getattr(self.OOTYPE, pname)
+ placeholder_val = getattr(self.OOTYPE, pval)
+ self.generics[placeholder] = (placeholder_val, ootype.ROOT)
+
+ def full_types(self, method_name):
+ """
+ Returns a tuple of argument and return types for the method
+ named 'method_name'. These are the actual generic types. The set method for
+ a list of strings, for example, might return:
+ ( [INT, STRING], VOID )
+ """
+ GENMETH = self.OOTYPE._GENERIC_METHODS[method_name]
+ ARGS, RESULT = (GENMETH.ARGS, GENMETH.RESULT)
+ ARGS = [self.generics.get(X,(X,))[0] for X in ARGS]
+ RESULT = self.generics.get(RESULT, (RESULT,))[0]
+ return (ARGS, RESULT)
+
+ def erased_types(self, method_name):
+ """
+ Returns a tuple of argument and return types for the method
+ named 'method_name'. These are the erased generic types. The set method for
+ a list of strings, for example, might return:
+ ( [INT, OBJECT], VOID )
+ """
+ GENMETH = self.OOTYPE._GENERIC_METHODS[method_name]
+ ARGS, RESULT = (GENMETH.ARGS, GENMETH.RESULT)
+ ARGS = [self.generics.get(X,(None,X))[1] for X in ARGS]
+ RESULT = self.generics.get(RESULT, (None,RESULT))[1]
+ return (ARGS, RESULT)
+
+
+
Modified: pypy/dist/pypy/translator/oosupport/constant.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/constant.py (original)
+++ pypy/dist/pypy/translator/oosupport/constant.py Thu Jan 11 18:15:11 2007
@@ -212,6 +212,11 @@
return genoo.DictConst(self.db, value, uniq)
elif isinstance(value, llmemory.fakeweakaddress):
return genoo.WeakRefConst(self.db, value, uniq)
+ elif value is ootype.null(value._TYPE):
+ # for NULL values, we can just use "NULL" const. This is
+ # a fallback since we sometimes have constants of
+ # unhandled types which are equal to NULL.
+ return genoo.NullConst(self.db, value, uniq)
else:
assert False, 'Unknown constant: %s' % value
@@ -407,6 +412,21 @@
# ______________________________________________________________________
+# Null Values
+#
+# NULL constants of types for which we have no better class use this
+# class. For example, dict item iterators and the like.
+
+class NullConst(AbstractConst):
+ def __init__(self, db, value, count):
+ AbstractConst.__init__(self, db, value, count)
+ self.name = 'NULL__%d' % count
+ assert self.is_null() and self.is_inline()
+
+ def record_dependencies(self):
+ return
+
+# ______________________________________________________________________
# Records
class RecordConst(AbstractConst):
@@ -627,11 +647,13 @@
gen.dup(SELFTYPE)
gen.add_comment(' key=%r value=%r' % (key,value))
push_constant(self.db, KEYTYPE, key, gen)
+ gen.prepare_generic_argument(KEYTYPE)
if VALUETYPE is ootype.Void:
# special case dict of Void; for now store the key as value?
gen.dup(KEYTYPE)
else:
push_constant(self.db, VALUETYPE, value, gen)
+ gen.prepare_generic_argument(VALUETYPE)
gen.call_method(SELFTYPE, 'll_set')
class CustomDictConst(DictConst):
Modified: pypy/dist/pypy/translator/oosupport/genoo.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/genoo.py (original)
+++ pypy/dist/pypy/translator/oosupport/genoo.py Thu Jan 11 18:15:11 2007
@@ -13,6 +13,7 @@
# _create_complex_const:
ConstantGenerator = None
+ NullConst = ooconst.NullConst
InstanceConst = ooconst.InstanceConst
RecordConst = ooconst.RecordConst
ClassConst = ooconst.ClassConst
Added: pypy/dist/pypy/translator/oosupport/test_template/dict.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/oosupport/test_template/dict.py Thu Jan 11 18:15:11 2007
@@ -0,0 +1,42 @@
+import py
+from pypy.rpython.test.test_rdict import TestOOtype as _TestOOtype
+from pypy.rpython.test.test_remptydict import BaseTestRemptydict
+from pypy.rpython.test.test_rconstantdict import BaseTestRconstantdict
+
+class BaseTestDict(_TestOOtype):
+ def test_dict_of_void(self):
+ class A: pass
+ def f():
+ d2 = {A(): None, A(): None}
+ return len(d2)
+ res = self.interpret(f, [])
+ assert res == 2
+
+ def test_dict_of_void_iter(self):
+ def f():
+ d = {1: None, 2: None, 3: None}
+ total = 0
+ for key, value in d.iteritems():
+ total += key
+ return total
+ assert self.interpret(f, []) == 6
+
+ def test_dict_of_dict(self):
+ py.test.skip("CLI doesn't support recursive dicts")
+
+ def test_recursive(self):
+ py.test.skip("CLI doesn't support recursive dicts")
+
+class BaseTestEmptyDict(BaseTestRemptydict):
+ def test_iterate_over_empty_dict(self):
+ py.test.skip("Iteration over empty dict is not supported, yet")
+
+class BaseTestConstantDict(BaseTestRconstantdict):
+ def test_constant_r_dict(self):
+ py.test.skip('r_dict is not supported, yet')
+
+ def test_tuple_as_key(self):
+ mydict = {('r',): 42}
+ def fn(ch):
+ return mydict[(ch,)]
+ assert self.interpret(fn, ['r']) == 42
From santagada at codespeak.net Thu Jan 11 18:48:35 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 18:48:35 +0100 (CET)
Subject: [pypy-svn] r36519 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070111174835.5E00F10063@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 18:48:33 2007
New Revision: 36519
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
ternary operator
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Thu Jan 11 18:48:33 2007
@@ -134,6 +134,7 @@
name = self.identifier.get_literal()
if name == 'print':
writer(",".join([i.GetValue().ToString() for i in self.arglist.get_args(ctx)]))
+ return w_Null
else:
w_obj = ctx.resolve_identifier(name).GetValue()
#print "arglist = ", self.arglist
@@ -145,6 +146,20 @@
self.left.eval(ctx)
return self.right.eval(ctx)
+class Conditional(Expression):
+ def __init__(self, logicalexpr, trueop, falseop):
+ self.logicalexpr = logicalexpr
+ self.trueop = trueop
+ self.falseop = falseop
+
+ def eval(self, ctx):
+ cond = self.logicalexpr.eval(ctx).GetValue().ToBoolean()
+ if cond == True:
+ return self.trueop.eval(ctx).GetValue()
+ else:
+ return self.falseop.eval(ctx).GetValue()
+
+
class Dot(BinaryOp):
def eval(self, ctx):
w_obj = self.left.eval(ctx).GetValue().ToObject()
@@ -533,6 +548,10 @@
return Call(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'COMMA':
return Comma(from_tree(gettreeitem(t, '0')),from_tree(gettreeitem(t, '1')))
+ elif tp == 'CONDITIONAL':
+ return Conditional(from_tree(gettreeitem(t, '0')),
+ from_tree(gettreeitem(t, '1')),
+ from_tree(gettreeitem(t, '2')))
elif tp == 'DOT':
return Dot(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'EQ':
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 18:48:33 2007
@@ -344,8 +344,10 @@
print(x)""", ["2"])
def test_ternaryop(self):
- py.test.skip(" TODO: needed for mozilla test suite")
- x = " ( t < 0 ) ? -1 : 1;"
+ self.assert_prints([
+ "( 1 == 1 ) ? print('yep') : print('nope');",
+ "( 1 == 0 ) ? print('yep') : print('nope');"],
+ ["yep","nope"])
def test_smallthings(self):
py.test.skip(" TODO: needed for mozilla test suite")
From santagada at codespeak.net Thu Jan 11 19:03:40 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 19:03:40 +0100 (CET)
Subject: [pypy-svn] r36521 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070111180340.31A8F10068@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 19:03:37 2007
New Revision: 36521
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
true and false work
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Thu Jan 11 19:03:37 2007
@@ -520,6 +520,13 @@
self.body.execute(ctx)
self.update.eval(ctx)
+class Boolean(Expression):
+ def __init__(self, bool):
+ self.bool = bool
+
+ def eval(self, ctx):
+ return W_Boolean(self.bool)
+
def getlist(t):
item = gettreeitem(t, 'length')
if item is None:
@@ -678,5 +685,9 @@
body = from_tree(gettreeitem(t, 'body'))
condition = from_tree(gettreeitem(t, 'condition'))
return While(condition, body)
+ elif tp == 'TRUE':
+ return Boolean(True)
+ elif tp == 'FALSE':
+ return Boolean(False)
else:
raise NotImplementedError("Dont know how to handler %s" % tp)
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 19:03:37 2007
@@ -349,6 +349,13 @@
"( 1 == 0 ) ? print('yep') : print('nope');"],
["yep","nope"])
+ def test_booleanliterals(self):
+ self.assert_prints("""
+ var x = false;
+ var y = true;
+ print(y)
+ print(x)""", ["true", "false"])
+
def test_smallthings(self):
py.test.skip(" TODO: needed for mozilla test suite")
x = """
From ericvrp at codespeak.net Thu Jan 11 19:26:41 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Thu, 11 Jan 2007 19:26:41 +0100 (CET)
Subject: [pypy-svn] r36522 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070111182641.15CC21005A@code0.codespeak.net>
Author: ericvrp
Date: Thu Jan 11 19:26:39 2007
New Revision: 36522
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
Log:
jit/codegen/llvm fix ptr_iszero, ptr_is_nonzero, getarraysize, and malloc_varsize operations
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Thu Jan 11 19:26:39 2007
@@ -11,8 +11,9 @@
trunc, zext, bitcast, shr_prefix, define, i8, i16, i32, f64
-pi8 = i8 + '*'
-u32 = i32
+pi8 = i8 + '*'
+pi32 = i32 + '*'
+u32 = i32
LINENO = option.lineno
PRINT_SOURCE = option.print_source
@@ -665,9 +666,10 @@
return gv_result
op_bool_is_true = op_char_is_true = op_unichar_is_true = op_int_is_true =\
- op_uint_is_true = op_ptr_nonzero = _is_true
-
- op_ptr_iszero = _is_false
+ op_uint_is_true = _is_true
+
+ def op_ptr_nonzero(self, gv_x): return self._is_true(gv_x, 'null')
+ def op_ptr_iszero(self, gv_x): return self._is_false(gv_x, 'null')
def op_float_is_true(self, gv_x): return self._is_true(gv_x, '0.0') #XXX fails for doubles
@@ -715,7 +717,7 @@
return self.returnvar(eax)
'''
#XXX TODO
- array_length_offset, array_items_offset, itemitem = arraytoken
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
gv_result = Var(i32)
log('%s Builder.genop_getarraysubstruct %s,%s,%s' % (
self.block.label, arraytoken, gv_ptr, gv_index))
@@ -724,18 +726,22 @@
return gv_result
def genop_getarraysize(self, arraytoken, gv_ptr):
- '''
- lengthoffset, startoffset, itemoffset = arraytoken
- self.mc.MOV(edx, gv_ptr.operand(self))
- return self.returnvar(mem(edx, lengthoffset))
- '''
- #XXX TODO
- array_length_offset, array_items_offset, itemtype = arraytoken
- gv_result = Var(i32)
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
log('%s Builder.genop_getarraysize %s,%s' % (
- self.block.label, arraytoken, gv_ptr))
- self.asm.append(' %s=%s 0 ;%s Builder.genop_getarraysize %s,%s' % (
- gv_result.operand2(), gv_result.type, self.block.label, arraytoken, gv_ptr))
+ self.block.label, arraytoken, gv_ptr.operand()))
+
+ gv_ptr_var = self._as_var(gv_ptr)
+
+ gv_p = Var(gv_ptr_var.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, array_length_offset))
+
+ gv_p2 = self._cast_to(gv_p, pi32)
+
+ gv_result = Var(i32)
+ self.asm.append(' %s=load %s' % (
+ gv_result.operand2(), gv_p2.operand()))
+
return gv_result
def _as_var(self, gv):
@@ -748,7 +754,7 @@
return gv
def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
- array_length_offset, array_items_offset, item_type = arraytoken
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
log('%s Builder.genop_getarrayitem %s,%s[%s]' % (
self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
@@ -771,7 +777,7 @@
return gv_result
def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
- array_length_offset, array_items_offset, item_type = arraytoken
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
log('%s Builder.genop_setarrayitem %s,%s[%s]=%s' % (
self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand(), gv_value.operand()))
@@ -796,7 +802,7 @@
t = pi8
gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
gv_result = Var(t)
- #XXX or use addGlobalFunctionMapping in libllvmjit.restart()
+ #or use addGlobalFunctionMapping in libllvmjit.restart()
self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr' % (
gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
@@ -807,16 +813,34 @@
def genop_malloc_varsize(self, varsizealloctoken, gv_size):
log('%s Builder.genop_malloc_varsize %s,%s' % (
self.block.label, varsizealloctoken, gv_size.operand()))
- t = pi8
- gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
- gv_result = Var(t)
- #XXX or use addGlobalFunctionMapping in libllvmjit.restart()
+
+ length_offset, items_offset, item_size, item_type = varsizealloctoken
+
+ gv_gc_malloc_fnaddr = Var('%s (%s)*' % (pi8, i32))
+ #or use addGlobalFunctionMapping in libllvmjit.restart()
self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr (varsize)' % (
gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
+
+ gv_size2 = Var(i32) #i386 uses self.itemaddr here
+ self.asm.append(' %s=mul %s,%d' % (
+ gv_size2.operand2(), gv_size.operand(), item_size))
+
+ gv_size3 = Var(i32)
+ self.asm.append(' %s=add %s,%d' % (
+ gv_size3.operand2(), gv_size2.operand(), items_offset))
+
+ gv_result = Var(pi8)
self.asm.append(' %s=call %s(%s)' % (
- gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), gv_size.operand()))
- #XXX TODO set length field
+ gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), gv_size3.operand()))
+
+ gv_p = Var(gv_result.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_result.operand(), i32, length_offset))
+
+ gv_p2 = self._cast_to(gv_p, pi32) #warning: length field hardcoded here
+ self.asm.append(' store %s, %s' % (gv_size.operand(), gv_p2.operand()))
+
return gv_result
def _funcsig_type(self, args_gv, restype):
@@ -1000,17 +1024,19 @@
arrayfield = T._arrayfld
ARRAYFIELD = getattr(T, arrayfield)
arraytoken = RLLVMGenOp.arrayToken(ARRAYFIELD)
- length_offset, items_offset, item_type = arraytoken
+ length_offset, items_offset, item_size, item_type = arraytoken
arrayfield_offset = llmemory.offsetof(T, arrayfield)
return (arrayfield_offset+length_offset,
arrayfield_offset+items_offset,
- item_type) #XXX was item_size
+ item_size,
+ item_type)
@staticmethod
@specialize.memo()
def arrayToken(A):
return (llmemory.ArrayLengthOffset(A),
llmemory.ArrayItemsOffset(A),
+ llmemory.ItemOffset(A.OF),
RLLVMGenOp.kindToken(A.OF))
@staticmethod
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Thu Jan 11 19:26:39 2007
@@ -71,11 +71,11 @@
test_simple_meth = skip
test_simple_red_meth = skip
test_degenerated_at_return = skip
+ test_degenerate_with_voids = skip
+ test_red_array = skip
#failing...
if skip_failing:
- test_degenerate_with_voids = skip
- test_red_array = skip
test_red_struct_array = skip
test_red_varsized_struct = skip
test_array_of_voids = skip
From cfbolz at codespeak.net Thu Jan 11 19:45:33 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Thu, 11 Jan 2007 19:45:33 +0100 (CET)
Subject: [pypy-svn] r36525 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070111184533.2957910060@code0.codespeak.net>
Author: cfbolz
Date: Thu Jan 11 19:45:32 2007
New Revision: 36525
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
Log:
food money update
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt Thu Jan 11 19:45:32 2007
@@ -1,16 +1,16 @@
-Armin Rigo -10 -8
-Anders Chrigstroem -10 -8
-Samuele Pedroni -10 -8
-Michael Hudson -10 -8
+Armin Rigo -10 -8 -8
+Anders Chrigstroem -10 -8 -8
+Samuele Pedroni -10 -8 -8
+Michael Hudson -10 -8 -8
Niko Matsakis
-Antonio Cuni -10 -8 +8
-Maciej Fijalkowski -10 -8 +110
-Eric van Riet Paap
-Jacob Hallen -10 -8
-Laura Creighton -10 -8
-Holger Krekel -10 -8
-Carl Friedrich Bolz -10 -8
-Guido Wesdorp -10 +134 -8
-Leonardo Santagada -10 -8
-Alexandre Fayolle -10 -8
-Sylvain Th?nault -10 -8
+Antonio Cuni -10 -8 +8 -8
+Maciej Fijalkowski -10 -8 +110 -8
+Eric van Riet Paap -8
+Jacob Hallen -10 -8 -8
+Laura Creighton -10 -8 -8
+Holger Krekel -10 -8 -8
+Carl Friedrich Bolz -10 -8 -8
+Guido Wesdorp -10 +134 -8 -8
+Leonardo Santagada -10 -8 -8
+Alexandre Fayolle -10 -8 +124 -8
+Sylvain Th?nault -10 -8 -
From niko at codespeak.net Thu Jan 11 19:50:15 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 19:50:15 +0100 (CET)
Subject: [pypy-svn] r36527 - in pypy/dist/pypy/translator/jvm: . test
Message-ID: <20070111185015.3880F10060@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 19:50:14 2007
New Revision: 36527
Modified:
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/test/runtest.py
pypy/dist/pypy/translator/jvm/test/test_dict.py
Log:
(antocuni, niko)
various fixes: we now support test_dict almost in its
entirety
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Thu Jan 11 19:50:14 2007
@@ -7,7 +7,7 @@
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm import typesystem as jvmtype
-from pypy.translator.jvm import node
+from pypy.translator.jvm import node, methods
from pypy.translator.jvm.option import getoption
import pypy.translator.jvm.generator as jvmgen
import pypy.translator.jvm.constant as jvmconst
@@ -110,10 +110,15 @@
# Add fields:
self._translate_class_fields(clsobj, OOTYPE)
- # TODO --- generate equals/hash methods here
-
- dump_method = node.RecordDumpMethod(self, OOTYPE, clsobj)
- clsobj.add_dump_method(dump_method)
+ # generate toString
+ dump_method = methods.RecordDumpMethod(self, OOTYPE, clsobj)
+ clsobj.add_method(dump_method)
+
+ # generate equals and hash
+ equals_method = methods.DeepEqualsMethod(self, OOTYPE, clsobj)
+ clsobj.add_method(equals_method)
+ hash_method = methods.DeepHashMethod(self, OOTYPE, clsobj)
+ clsobj.add_method(hash_method)
self.pending_node(clsobj)
return clsobj
@@ -169,7 +174,7 @@
# currently, we always include a special "dump" method for debugging
# purposes
dump_method = node.InstanceDumpMethod(self, OOTYPE, clsobj)
- clsobj.add_dump_method(dump_method)
+ clsobj.add_method(dump_method)
self.pending_node(clsobj)
return clsobj
@@ -236,10 +241,10 @@
return n
# _________________________________________________________________
- # Type printing functions
+ # toString functions
#
- # Returns a method that prints details about the value out to
- # stdout. Should generalize to make it allow for stderr as well.
+ # Obtains an appropriate method for serializing an object of
+ # any type.
_toString_methods = {
ootype.Signed:jvmgen.INTTOSTRINGI,
@@ -252,7 +257,7 @@
ootype.String:jvmgen.PYPYESCAPEDSTRING,
}
- def generate_toString_method_for_ootype(self, OOTYPE):
+ def toString_method_for_ootype(self, OOTYPE):
"""
Assuming than an instance of type OOTYPE is pushed on the
stack, returns a Method object that you can invoke. This method
@@ -261,7 +266,7 @@
Do something like:
> gen.load(var)
- > mthd = db.generate_toString_method_for_ootype(var.concretetype)
+ > mthd = db.toString_method_for_ootype(var.concretetype)
> mthd.invoke(gen)
to print the value of 'var'.
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Thu Jan 11 19:50:14 2007
@@ -181,6 +181,7 @@
LDC2 = Opcode('ldc2_w') # double-word types: doubles and longs
GOTO = Opcode('goto')
ICONST = IntConstOpcode('iconst')
+ICONST_0 = Opcode('iconst_0') # sometimes convenient to refer to this directly
ACONST_NULL=Opcode('aconst_null')
DCONST_0 = Opcode('dconst_0')
DCONST_1 = Opcode('dconst_0')
@@ -203,6 +204,7 @@
ISHL = Opcode('ishl')
ISHR = Opcode('ishr')
IUSHR = Opcode('iushr')
+LCMP = Opcode('lcmp')
DCMPG = Opcode('dcmpg')
DCMPL = Opcode('dcmpl')
NOP = Opcode('nop')
@@ -332,6 +334,7 @@
OBJHASHCODE = Method.v(jObject, 'hashCode', (), jInt)
OBJTOSTRING = Method.v(jObject, 'toString', (), jString)
+OBJEQUALS = Method.v(jObject, 'equals', (jObject,), jBool)
INTTOSTRINGI = Method.s(jIntegerClass, 'toString', (jInt,), jString)
LONGTOSTRINGL = Method.s(jLongClass, 'toString', (jLong,), jString)
DOUBLETOSTRINGD = Method.s(jDoubleClass, 'toString', (jDouble,), jString)
@@ -756,7 +759,49 @@
'catchlbl' --- label marking beginning of catch region
"""
unimplemented
-
+
+ _equals = {
+ ootype.Void: (None,None),
+ ootype.SignedLongLong: (LCMP,IFEQ),
+ ootype.UnsignedLongLong: (LCMP,IFEQ),
+ ootype.Float: (DCMPG,IFEQ),
+ ootype.Signed: (None,IF_ICMPNE),
+ ootype.Unsigned: (None,IF_ICMPNE),
+ ootype.Bool: (None,IF_ICMPNE),
+ ootype.Char: (None,IF_ICMPNE),
+ ootype.UniChar: (None,IF_ICMPNE),
+ }
+ def compare_values(self, OOTYPE, unequal_lbl):
+ """ Assumes that two instances of OOTYPE are pushed on the stack;
+ compares them and jumps to 'unequal_lbl' if they are unequal """
+ if OOTYPE in self._equals:
+ i1, i2 = self._equals[OOTYPE]
+ if i1: self.emit(i1)
+ if i2: self.emit(i2, unequal_lbl)
+ return
+ self.emit(OBJEQUALS)
+ self.emit(IFEQ, unequal_lbl)
+
+ _hash = {
+ ootype.Void: ICONST_0,
+ ootype.SignedLongLong: L2I,
+ ootype.UnsignedLongLong: L2I,
+ ootype.Float: D2I,
+ ootype.Signed: None,
+ ootype.Unsigned: None,
+ ootype.Bool: None,
+ ootype.Char: None,
+ ootype.UniChar: None,
+ }
+ def hash_value(self, OOTYPE):
+ """ Assumes that an instance of OOTYPE is pushed on the stack.
+ When finished, an int will be on the stack as a hash value. """
+ if OOTYPE in self._hash:
+ i1 = self._hash[OOTYPE]
+ if i1: self.emit(i1)
+ return
+ self.emit(OBJHASHCODE)
+
# __________________________________________________________________
# Generator methods and others that are invoked by MicroInstructions
#
@@ -991,6 +1036,10 @@
""" Jumps if the top of stack is true """
self._instr(IFNE, label)
+ def goto_if_false(self, label):
+ """ Jumps if the top of stack is false """
+ self._instr(IFEQ, label)
+
##### Comparison methods
def _compare_op(self, cmpopcode):
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 19:50:14 2007
@@ -14,16 +14,26 @@
"""
-from pypy.objspace.flow import model as flowmodel
-from pypy.rpython.lltypesystem import lltype
-from pypy.rpython.ootypesystem import ootype, rclass
+from pypy.objspace.flow import \
+ model as flowmodel
+from pypy.rpython.lltypesystem import \
+ lltype
+from pypy.rpython.ootypesystem import \
+ ootype, rclass
from pypy.translator.jvm.typesystem import \
JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, jPyPyMain, \
jObject, JvmType, jStringBuilder
-from pypy.translator.jvm.opcodes import opcodes
-from pypy.translator.jvm.option import getoption
-from pypy.translator.oosupport.function import Function as OOFunction
-from pypy.translator.oosupport.constant import push_constant
+from pypy.translator.jvm.opcodes import \
+ opcodes
+from pypy.translator.jvm.option import \
+ getoption
+from pypy.translator.jvm.methods import \
+ BaseDumpMethod, InstanceDumpMethod, RecordDumpMethod, ConstantStringDumpMethod
+from pypy.translator.oosupport.function import \
+ Function as OOFunction
+from pypy.translator.oosupport.constant import \
+ push_constant
+
import pypy.translator.jvm.generator as jvmgen
class Node(object):
@@ -114,7 +124,7 @@
if self.print_result:
done_printing = gen.unique_label('done_printing')
RESOOTYPE = self.graph.getreturnvar().concretetype
- dumpmethod = self.db.generate_toString_method_for_ootype(RESOOTYPE)
+ dumpmethod = self.db.toString_method_for_ootype(RESOOTYPE)
gen.add_comment('Invoking dump method for result of type '
+str(RESOOTYPE))
gen.emit(dumpmethod) # generate the string
@@ -256,26 +266,58 @@
self.generator.load_string(str)
jvmgen.PRINTSTREAMPRINTSTR.invoke(self.generator)
+ def _is_printable(self, res):
+
+ if res.concretetype in (
+ ootype.Instance,
+ ootype.Signed,
+ ootype.Unsigned,
+ ootype.SignedLongLong,
+ ootype.UnsignedLongLong,
+ ootype.Bool,
+ ootype.Float,
+ ootype.Char,
+ ootype.UniChar,
+ ootype.String,
+ ootype.StringBuilder,
+ ootype.Class):
+ return True
+
+ if isinstance(res.concretetype, (
+ ootype.Instance,
+ ootype.Record,
+ ootype.List,
+ ootype.Dict,
+ ootype.DictItemsIterator)):
+ return True
+
+ return False
+
+ def _trace_value(self, prompt, res):
+ if res and self._is_printable(res):
+ jmethod = self.db.toString_method_for_ootype(
+ res.concretetype)
+
+ self._trace(" "+prompt+": ")
+ self.generator.emit(jvmgen.SYSTEMERR)
+ self.generator.load(res)
+ self.generator.emit(jmethod)
+ self.generator.emit(jvmgen.PRINTSTREAMPRINTSTR)
+ self._trace("\n")
+
def _render_op(self, op):
self.generator.add_comment(str(op))
if getoption('trace'):
self._trace(str(op)+"\n")
+ for i, arg in enumerate(op.args):
+ self._trace_value('Arg %02d' % i, arg)
+
OOFunction._render_op(self, op)
- if (getoption('trace')
- and op.result
- and op.result.concretetype is not ootype.Void):
- self._trace(" Result: ")
- res = op.result
- jmethod = self.db.generate_toString_method_for_ootype(
- res.concretetype)
- jvmgen.SYSTEMERR.load(self.generator)
- self.generator.load(res)
- self.generator.emit(jmethod)
- jvmgen.PRINTSTREAMPRINTSTR.invoke(self.generator)
- self._trace("\n")
+ if getoption('trace'):
+ self._trace_value('Result', op.result)
class StaticMethodInterface(Node, JvmClassType):
"""
@@ -417,10 +459,6 @@
self.abstract = True
self.abstract_methods[jmethod.method_name] = jmethod
- def add_dump_method(self, dm):
- self.dump_method = dm # public attribute for reading
- self.add_method(dm)
-
def render(self, gen):
self.rendered = True
gen.begin_class(self, self.super_class, abstract=self.abstract)
@@ -451,107 +489,3 @@
gen.end_function()
gen.end_class()
-
-class BaseDumpMethod(object):
-
- def __init__(self, db, OOCLASS, clsobj):
- self.db = db
- self.OOCLASS = OOCLASS
- self.clsobj = clsobj
- self.name = "toString"
- self.jargtypes = [clsobj]
- self.jrettype = jString
-
- def _print_field_value(self, fieldnm, FIELDOOTY):
- self.gen.emit(jvmgen.DUP)
- self.gen.load_this_ptr()
- fieldobj = self.clsobj.lookup_field(fieldnm)
- fieldobj.load(self.gen)
- dumpmethod = self.db.generate_toString_method_for_ootype(FIELDOOTY)
- self.gen.emit(dumpmethod)
- self.gen.emit(jvmgen.PYPYAPPEND)
-
- def _print(self, str):
- self.gen.emit(jvmgen.DUP)
- self.gen.load_string(str)
- self.gen.emit(jvmgen.PYPYAPPEND)
-
- def render(self, gen):
- self.gen = gen
- gen.begin_function(
- self.name, (), self.jargtypes, self.jrettype, static=False)
-
- gen.new_with_jtype(jStringBuilder)
- self._render_guts(gen)
- gen.emit(jvmgen.OBJTOSTRING)
- gen.emit(jvmgen.RETURN.for_type(jString))
- gen.end_function()
- self.gen = None
-
-class InstanceDumpMethod(BaseDumpMethod):
-
- def _render_guts(self, gen):
- clsobj = self.clsobj
- genprint = self._print
-
- # Start the dump
- genprint("InstanceWrapper(")
- genprint("'" + self.OOCLASS._name + "', ")
- genprint("{")
-
- for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
-
- if FIELDOOTY is ootype.Void: continue
-
- genprint('"'+fieldnm+'":')
-
- print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
-
- # Print the value of the field:
- self._print_field_value(fieldnm, FIELDOOTY)
-
- # Dump close
- genprint("})")
-
-class RecordDumpMethod(BaseDumpMethod):
-
- def _render_guts(self, gen):
- clsobj = self.clsobj
- genprint = self._print
-
- # We only render records that represent tuples:
- # In that case, the field names look like item0, item1, etc
- # Otherwise, we just do nothing... this is because we
- # never return records that do not represent tuples from
- # a testing function
- for f_name in self.OOCLASS._fields:
- if not f_name.startswith('item'):
- return
-
- # Start the dump
- genprint("StructTuple((")
-
- numfields = len(self.OOCLASS._fields)
- for i in range(numfields):
- f_name = 'item%d' % i
- FIELD_TYPE, f_default = self.OOCLASS._fields[f_name]
- if FIELD_TYPE is ootype.Void:
- continue
-
- # Print the value of the field:
- self._print_field_value(f_name, FIELD_TYPE)
- genprint(',')
-
- # Decrement indent and dump close
- genprint("))")
-
-class ConstantStringDumpMethod(BaseDumpMethod):
- """ Just prints out a string """
-
- def __init__(self, clsobj, str):
- BaseDumpMethod.__init__(self, None, None, clsobj)
- self.constant_string = str
-
- def _render_guts(self, gen):
- genprint = self._print
- genprint("'" + self.constant_string + "'")
Modified: pypy/dist/pypy/translator/jvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/runtest.py (original)
+++ pypy/dist/pypy/translator/jvm/test/runtest.py Thu Jan 11 19:50:14 2007
@@ -15,8 +15,9 @@
FLOAT_PRECISION = 8
-# CLI duplicate
class StructTuple(tuple):
+ def __init__(self, class_name, value):
+ tuple.__init__(self, value)
def __getattr__(self, name):
if name.startswith('item'):
i = int(name[len('item'):])
Modified: pypy/dist/pypy/translator/jvm/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/test_dict.py (original)
+++ pypy/dist/pypy/translator/jvm/test/test_dict.py Thu Jan 11 19:50:14 2007
@@ -1,8 +1,10 @@
+import py
from pypy.translator.jvm.test.runtest import JvmTest
import pypy.translator.oosupport.test_template.dict as oodict
class TestJvmDict(JvmTest, oodict.BaseTestDict):
- pass
+ def test_invalid_iterator(self):
+ py.test.skip("test_invalid_iterator() doesn't work yet")
class TestJvmEmptyDict(JvmTest, oodict.BaseTestEmptyDict):
pass
From niko at codespeak.net Thu Jan 11 19:53:21 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 19:53:21 +0100 (CET)
Subject: [pypy-svn] r36528 - pypy/dist/pypy/translator/jvm
Message-ID: <20070111185321.1085010060@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 19:53:21 2007
New Revision: 36528
Added:
pypy/dist/pypy/translator/jvm/methods.py
Log:
forgot to add this!
Added: pypy/dist/pypy/translator/jvm/methods.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/methods.py Thu Jan 11 19:53:21 2007
@@ -0,0 +1,210 @@
+"""
+
+Special methods which we hand-generate, such as toString(), equals(), and hash().
+
+These are generally added to methods listing of node.Class, and the
+only requirement is that they must have a render(self, gen) method.
+
+"""
+
+import pypy.translator.jvm.generator as jvmgen
+import pypy.translator.jvm.typesystem as jvmtype
+from pypy.rpython.ootypesystem import ootype, rclass
+
+class BaseDumpMethod(object):
+
+ def __init__(self, db, OOCLASS, clsobj):
+ self.db = db
+ self.OOCLASS = OOCLASS
+ self.clsobj = clsobj
+ self.name = "toString"
+ self.jargtypes = [clsobj]
+ self.jrettype = jvmtype.jString
+
+ def _print_field_value(self, fieldnm, FIELDOOTY):
+ self.gen.emit(jvmgen.DUP)
+ self.gen.load_this_ptr()
+ fieldobj = self.clsobj.lookup_field(fieldnm)
+ fieldobj.load(self.gen)
+ dumpmethod = self.db.toString_method_for_ootype(FIELDOOTY)
+ self.gen.emit(dumpmethod)
+ self.gen.emit(jvmgen.PYPYAPPEND)
+
+ def _print(self, str):
+ self.gen.emit(jvmgen.DUP)
+ self.gen.load_string(str)
+ self.gen.emit(jvmgen.PYPYAPPEND)
+
+ def render(self, gen):
+ self.gen = gen
+ gen.begin_function(
+ self.name, (), self.jargtypes, self.jrettype, static=False)
+
+ gen.new_with_jtype(jvmtype.jStringBuilder)
+ self._render_guts(gen)
+ gen.emit(jvmgen.OBJTOSTRING)
+ gen.emit(jvmgen.RETURN.for_type(jvmtype.jString))
+ gen.end_function()
+ self.gen = None
+
+class InstanceDumpMethod(BaseDumpMethod):
+
+ def _render_guts(self, gen):
+ clsobj = self.clsobj
+ genprint = self._print
+
+ # Start the dump
+ genprint("InstanceWrapper(")
+ genprint("'" + self.OOCLASS._name + "', ")
+ genprint("{")
+
+ for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
+
+ if FIELDOOTY is ootype.Void: continue
+
+ genprint('"'+fieldnm+'":')
+
+ print "fieldnm=%r fieldty=%r" % (fieldnm, FIELDOOTY)
+
+ # Print the value of the field:
+ self._print_field_value(fieldnm, FIELDOOTY)
+
+ # Dump close
+ genprint("})")
+
+class RecordDumpMethod(BaseDumpMethod):
+
+ def _render_guts(self, gen):
+ clsobj = self.clsobj
+ genprint = self._print
+
+ # We only render records that represent tuples:
+ # In that case, the field names look like item0, item1, etc
+ # Otherwise, we just do nothing... this is because we
+ # never return records that do not represent tuples from
+ # a testing function
+ for f_name in self.OOCLASS._fields:
+ if not f_name.startswith('item'):
+ return
+
+ # Start the dump
+ genprint("StructTuple(")
+ genprint("'" + self.clsobj.name + "', ")
+ genprint("(")
+
+ numfields = len(self.OOCLASS._fields)
+ for i in range(numfields):
+ f_name = 'item%d' % i
+ FIELD_TYPE, f_default = self.OOCLASS._fields[f_name]
+ if FIELD_TYPE is ootype.Void:
+ continue
+
+ # Print the value of the field:
+ self._print_field_value(f_name, FIELD_TYPE)
+ genprint(',')
+
+ # Decrement indent and dump close
+ genprint("))")
+
+class ConstantStringDumpMethod(BaseDumpMethod):
+ """ Just prints out a string """
+
+ def __init__(self, clsobj, str):
+ BaseDumpMethod.__init__(self, None, None, clsobj)
+ self.constant_string = str
+
+ def _render_guts(self, gen):
+ genprint = self._print
+ genprint("'" + self.constant_string + "'")
+
+class DeepEqualsMethod(object):
+
+ def __init__(self, db, OOCLASS, clsobj):
+ self.db = db
+ self.OOCLASS = OOCLASS
+ self.clsobj = clsobj
+ self.name = "equals"
+ self.jargtypes = [clsobj, jvmtype.jObject]
+ self.jrettype = jvmtype.jBool
+
+ def render(self, gen):
+ self.gen = gen
+ gen.begin_function(
+ self.name, (), self.jargtypes, self.jrettype, static=False)
+
+ # Label to branch to should the items prove to be unequal
+ unequal_lbl = gen.unique_label('unequal')
+
+ gen.add_comment('check that the argument is of the correct type')
+ gen.load_jvm_var(self.clsobj, 1)
+ gen.instanceof(self.OOCLASS)
+ gen.goto_if_false(unequal_lbl)
+
+ gen.add_comment('Cast it to the right type:')
+ gen.load_jvm_var(self.clsobj, 1)
+ gen.downcast(self.OOCLASS)
+ gen.store_jvm_var(self.clsobj, 1)
+
+ # If so, compare field by field
+ for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
+ if FIELDOOTY is ootype.Void: continue
+ fieldobj = self.clsobj.lookup_field(fieldnm)
+
+ gen.add_comment('Compare field %s of type %s' % (fieldnm, FIELDOOTY))
+
+ # Load the field from both this and the argument:
+ gen.load_jvm_var(self.clsobj, 0)
+ gen.emit(fieldobj)
+ gen.load_jvm_var(self.clsobj, 1)
+ gen.emit(fieldobj)
+
+ # And compare them:
+ gen.compare_values(FIELDOOTY, unequal_lbl)
+
+ # Return true or false as appropriate
+ gen.push_primitive_constant(ootype.Bool, True)
+ gen.return_val(jvmtype.jBool)
+ gen.mark(unequal_lbl)
+ gen.push_primitive_constant(ootype.Bool, False)
+ gen.return_val(jvmtype.jBool)
+
+ gen.end_function()
+
+class DeepHashMethod(object):
+
+ def __init__(self, db, OOCLASS, clsobj):
+ self.db = db
+ self.OOCLASS = OOCLASS
+ self.clsobj = clsobj
+ self.name = "hashCode"
+ self.jargtypes = [clsobj]
+ self.jrettype = jvmtype.jInt
+
+ def render(self, gen):
+ self.gen = gen
+ gen.begin_function(
+ self.name, (), self.jargtypes, self.jrettype, static=False)
+
+ # Initial hash: 0
+ gen.push_primitive_constant(ootype.Signed, 0)
+
+ # Get hash of each field
+ for fieldnm, (FIELDOOTY, fielddef) in self.OOCLASS._fields.iteritems():
+ if FIELDOOTY is ootype.Void: continue
+ fieldobj = self.clsobj.lookup_field(fieldnm)
+
+ gen.add_comment('Hash field %s of type %s' % (fieldnm, FIELDOOTY))
+
+ # Load the field and hash it:
+ gen.load_jvm_var(self.clsobj, 0)
+ gen.emit(fieldobj)
+ gen.hash_value(FIELDOOTY)
+
+ # XOR that with the main hash
+ gen.emit(jvmgen.IXOR)
+
+ # Return the final hash
+ gen.return_val(jvmtype.jInt)
+
+ gen.end_function()
+
From santagada at codespeak.net Thu Jan 11 19:56:11 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Thu, 11 Jan 2007 19:56:11 +0100 (CET)
Subject: [pypy-svn] r36529 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070111185611.F172D1007D@code0.codespeak.net>
Author: santagada
Date: Thu Jan 11 19:56:10 2007
New Revision: 36529
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
NOT unary operator
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Thu Jan 11 19:56:10 2007
@@ -527,6 +527,13 @@
def eval(self, ctx):
return W_Boolean(self.bool)
+class Not(Expression):
+ def __init__(self, op):
+ self.op = op
+
+ def eval(self, ctx):
+ return W_Boolean(not self.op.eval(ctx).GetValue().ToBoolean())
+
def getlist(t):
item = gettreeitem(t, 'length')
if item is None:
@@ -689,5 +696,7 @@
return Boolean(True)
elif tp == 'FALSE':
return Boolean(False)
+ elif tp == 'NOT':
+ return Not(from_tree(gettreeitem(t, '0')))
else:
raise NotImplementedError("Dont know how to handler %s" % tp)
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Thu Jan 11 19:56:10 2007
@@ -356,6 +356,12 @@
print(y)
print(x)""", ["true", "false"])
+ def test_unarynot(self):
+ self.assert_prints("""
+ var x = false;
+ print(!x)
+ print(!!x)""", ["true", "false"])
+
def test_smallthings(self):
py.test.skip(" TODO: needed for mozilla test suite")
x = """
From niko at codespeak.net Thu Jan 11 20:00:08 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 20:00:08 +0100 (CET)
Subject: [pypy-svn] r36530 - in pypy/dist/pypy/translator/jvm: . test
Message-ID: <20070111190008.9F6D21007D@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 20:00:06 2007
New Revision: 36530
Modified:
pypy/dist/pypy/translator/jvm/methods.py
pypy/dist/pypy/translator/jvm/test/runtest.py
Log:
remove debugging information from StructTuple to fix a few tests...
Modified: pypy/dist/pypy/translator/jvm/methods.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/methods.py (original)
+++ pypy/dist/pypy/translator/jvm/methods.py Thu Jan 11 20:00:06 2007
@@ -88,9 +88,7 @@
return
# Start the dump
- genprint("StructTuple(")
- genprint("'" + self.clsobj.name + "', ")
- genprint("(")
+ genprint("StructTuple((")
numfields = len(self.OOCLASS._fields)
for i in range(numfields):
Modified: pypy/dist/pypy/translator/jvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/runtest.py (original)
+++ pypy/dist/pypy/translator/jvm/test/runtest.py Thu Jan 11 20:00:06 2007
@@ -16,8 +16,6 @@
FLOAT_PRECISION = 8
class StructTuple(tuple):
- def __init__(self, class_name, value):
- tuple.__init__(self, value)
def __getattr__(self, name):
if name.startswith('item'):
i = int(name[len('item'):])
From afayolle at codespeak.net Thu Jan 11 20:03:26 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Thu, 11 Jan 2007 20:03:26 +0100 (CET)
Subject: [pypy-svn] r36531 - in pypy/dist/pypy: config translator/goal
Message-ID: <20070111190326.BE1C71007E@code0.codespeak.net>
Author: afayolle
Date: Thu Jan 11 20:03:26 2007
New Revision: 36531
Removed:
pypy/dist/pypy/translator/goal/targetlogicstandalone.py
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
no longer use targetlogicstandalone: targetpypystandalone -o logic does what is required
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Thu Jan 11 20:03:26 2007
@@ -39,7 +39,10 @@
requires = {
"thunk": [("objspace.geninterp", False)],
"logic": [("objspace.geninterp", False),
- ("objspace.usemodules._stackless", True)],
+ ("objspace.usemodules._stackless", True),
+ ("translation.debug", True),
+ ("translation.gc", 'framework'),
+ ],
},
cmdline='--objspace -o'),
From antocuni at codespeak.net Thu Jan 11 22:25:59 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Thu, 11 Jan 2007 22:25:59 +0100 (CET)
Subject: [pypy-svn] r36533 - pypy/dist/pypy/translator/cli
Message-ID: <20070111212559.92D8410061@code0.codespeak.net>
Author: antocuni
Date: Thu Jan 11 22:25:58 2007
New Revision: 36533
Modified:
pypy/dist/pypy/translator/cli/class_.py
Log:
remove print debug.
Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py (original)
+++ pypy/dist/pypy/translator/cli/class_.py Thu Jan 11 22:25:58 2007
@@ -132,7 +132,6 @@
f_name = self.cts.escape_name(f_name)
if cts_type != 'void':
self.ilasm.opcode('ldarg.0')
- print "%s f_default=%s" % (self.name, f_default)
push_constant(self.db, F_TYPE, f_default, self.gen)
class_name = self.db.class_name(self.INSTANCE)
self.ilasm.set_field((cts_type, class_name, f_name))
From niko at codespeak.net Thu Jan 11 22:26:21 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Thu, 11 Jan 2007 22:26:21 +0100 (CET)
Subject: [pypy-svn] r36534 - pypy/dist/pypy/translator/jvm
Message-ID: <20070111212621.5217D10070@code0.codespeak.net>
Author: niko
Date: Thu Jan 11 22:26:19 2007
New Revision: 36534
Modified:
pypy/dist/pypy/translator/jvm/node.py
Log:
purge debug print out
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Thu Jan 11 22:26:19 2007
@@ -473,8 +473,6 @@
if field.jtype is not jVoid:
gen.load_jvm_var(self, 0) # load this ptr
# load default value of field
- print "%s f_name=%s f_default=%s" % (
- self.name, field.field_name, f_default)
push_constant(gen.db, field.OOTYPE, f_default, gen)
field.store(gen) # store value into field
gen.end_constructor()
From niko at codespeak.net Fri Jan 12 00:12:41 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Fri, 12 Jan 2007 00:12:41 +0100 (CET)
Subject: [pypy-svn] r36536 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070111231241.241F810068@code0.codespeak.net>
Author: niko
Date: Fri Jan 12 00:12:34 2007
New Revision: 36536
Modified:
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
Expand the set of operations, and make them handle immediates
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Jan 12 00:12:34 2007
@@ -610,28 +610,39 @@
gv_result, [gv_x, gv_y]))
return gv_result
- def op_int_add(self, gv_x, gv_y):
+ def generic_int_op(self, gv_x, gv_y, commutative, opcode, opcodei):
gv_result = Var()
if gv_y.fits_in_immediate():
self.insns.append(
- insn.Insn_GPR__GPR_IMM(RPPCAssembler.addi,
+ insn.Insn_GPR__GPR_IMM(opcodei,
gv_result, [gv_x, gv_y]))
- elif gv_x.fits_in_immediate():
+ elif gv_x.fits_in_immediate() and commutative:
self.insns.append(
- insn.Insn_GPR__GPR_IMM(RPPCAssembler.addi,
+ insn.Insn_GPR__GPR_IMM(opcodei,
gv_result, [gv_y, gv_x]))
else:
self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.add,
+ insn.Insn_GPR__GPR_GPR(opcode,
gv_result, [gv_x, gv_y]))
return gv_result
+
+ def op_int_add(self, gv_x, gv_y):
+ return self.generic_int_op(gv_x, gv_y, True, RPPCAssembler.add, RPPCAssembler.addi)
+
+ op_uint_add = op_int_add
def op_int_sub(self, gv_x, gv_y):
- gv_result = Var()
- self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.sub,
- gv_result, [gv_x, gv_y]))
- return gv_result
+ return self.generic_int_op(gv_x, gv_y, False, RPPCAssembler.sub, RPPCAssembler.subi)
+
+ def op_int_xor(self, gv_x, gv_y):
+ return self.generic_int_op(gv_x, gv_y, True, RPPCAssembler.xor, RPPCAssembler.xori)
+
+ op_uint_xor = op_int_xor
+
+ def op_int_and(self, gv_x, gv_y):
+ return self.generic_int_op(gv_x, gv_y, True, RPPCAssembler.and_, RPPCAssembler.andix)
+
+ op_uint_and = op_int_and
def op_int_floordiv(self, gv_x, gv_y):
gv_result = Var()
@@ -716,9 +727,16 @@
insn.Insn_GPR__GPR(RPPCAssembler.neg, gv_result, gv_arg))
return gv_result
+ def identity(self, gv_x):
+ return gv_x
+
op_ptr_nonzero = op_int_is_true
op_ptr_iszero = op_bool_not # for now
+ op_ptr_ne = op_int_ne
+ op_ptr_eq = op_int_eq
+ op_cast_uint_to_int = identity
+ op_cast_int_to_uint = identity
class RPPCGenOp(AbstractRGenOp):
From fijal at codespeak.net Fri Jan 12 11:05:17 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 11:05:17 +0100 (CET)
Subject: [pypy-svn] r36544 - in pypy/dist/pypy/annotation: . test
Message-ID: <20070112100517.929FC1006F@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 11:05:12 2007
New Revision: 36544
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/model.py
pypy/dist/pypy/annotation/test/test_annrpython.py
pypy/dist/pypy/annotation/unaryop.py
Log:
(arigo, fijal) - variable renaming and additional check.
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Fri Jan 12 11:05:12 2007
@@ -686,7 +686,9 @@
class __extend__(pairtype(SomeGenericCallable, SomePBC)):
def union((gencall, pbc)):
unique_key = (gencall, pbc.const)
- getbookkeeper().emulate_pbc_call(unique_key, pbc, gencall.args_s)
+ s_result = getbookkeeper().emulate_pbc_call(unique_key, pbc,
+ gencall.args_s)
+ assert gencall.s_result.contains(s_result)
return gencall
class __extend__(pairtype(SomeImpossibleValue, SomeObject)):
Modified: pypy/dist/pypy/annotation/model.py
==============================================================================
--- pypy/dist/pypy/annotation/model.py (original)
+++ pypy/dist/pypy/annotation/model.py Fri Jan 12 11:05:12 2007
@@ -35,7 +35,7 @@
from pypy.rlib.rarithmetic import r_uint, r_longlong, r_ulonglong, base_int
import inspect
from sys import maxint
-
+from pypy.annotation.description import FunctionDesc
DEBUG = True # set to False to disable recording of debugging information
TLS = tlsobject()
@@ -396,9 +396,12 @@
class SomeGenericCallable(SomeObject):
""" Stands for external callable with known signature
"""
- def __init__(self, args, retval):
+ def __init__(self, args, result):
self.args_s = args
- self.retval_s = retval
+ self.s_result = result
+
+ def can_be_None(self):
+ return True
class SomeBuiltin(SomeObject):
"Stands for a built-in function or method with special-cased analysis."
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Fri Jan 12 11:05:12 2007
@@ -2454,10 +2454,11 @@
def g(a):
pass
g._known_annotation_ = annmodel.SomeGenericCallable(
- args=(annmodel.SomeInteger(),), retval=annmodel.SomeInteger())
+ args=(annmodel.SomeInteger(),), result=annmodel.SomeInteger())
def fun():
return g(1)
+
a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
s = a.build_types(fun, [])
assert isinstance(s, annmodel.SomeInteger)
@@ -2468,8 +2469,8 @@
pass
g._known_annotation_ = annmodel.SomeGenericCallable(
args=[annmodel.SomeGenericCallable(args=[annmodel.SomeInteger()],
- retval=annmodel.SomeInteger())],
- retval=annmodel.SomeInteger())
+ result=annmodel.SomeInteger())],
+ result=annmodel.SomeInteger())
def fun2(x):
return x
Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py (original)
+++ pypy/dist/pypy/annotation/unaryop.py Fri Jan 12 11:05:12 2007
@@ -605,7 +605,8 @@
bookkeeper = getbookkeeper()
for arg, expected in zip(args.unpack()[0], self.args_s):
assert expected.contains(arg)
- return self.retval_s
+
+ return self.s_result
class __extend__(SomeExternalObject):
def find_method(obj, name):
From pedronis at codespeak.net Fri Jan 12 11:55:58 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 12 Jan 2007 11:55:58 +0100 (CET)
Subject: [pypy-svn] r36545 - pypy/dist/pypy/jit/timeshifter/test
Message-ID: <20070112105558.6ABB610071@code0.codespeak.net>
Author: pedronis
Date: Fri Jan 12 11:55:56 2007
New Revision: 36545
Modified:
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
new test about virtualizable used across residual calls
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Fri Jan 12 11:55:56 2007
@@ -512,3 +512,54 @@
res = self.timeshift_from_portal(main, f, [0, 21],
policy=StopAtGPolicy())
assert res == 42
+
+ def test_explicit_residual_red_call(self):
+ py.test.skip("WIP")
+
+ def g(e):
+ xy = e.xy
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ e.w = y
+
+ def f(e):
+ xy = e.xy
+ xy_access = xy.access
+ if xy_access:
+ y = xy_access.get_y(xy)
+ else:
+ y = xy.y
+ xy_access = xy.access
+ newy = 2*y
+ if xy_access:
+ xy_access.set_y(xy, newy)
+ else:
+ xy.y = newy
+ g(e)
+ return xy.x
+
+ def main(x, y):
+ xy = lltype.malloc(XY)
+ xy.access = lltype.nullptr(XY_ACCESS)
+ xy.x = x
+ xy.y = y
+ e = lltype.malloc(E)
+ e.xy = xy
+ v = f(e)
+ return v+e.w
+
+
+ class StopAtGPolicy(HintAnnotatorPolicy):
+ novirtualcontainer = True
+
+ def look_inside_graph(self, graph):
+ if graph.name == 'g':
+ return False
+ return True
+
+ res = self.timeshift_from_portal(main, f, [2, 20],
+ policy=StopAtGPolicy())
+ assert res == 42
From fijal at codespeak.net Fri Jan 12 12:09:28 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 12:09:28 +0100 (CET)
Subject: [pypy-svn] r36548 - in pypy/dist/pypy/rpython: . test
Message-ID: <20070112110928.5A8DE10078@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 12:09:26 2007
New Revision: 36548
Added:
pypy/dist/pypy/rpython/extfunc.py
pypy/dist/pypy/rpython/test/test_extfunc.py
Modified:
pypy/dist/pypy/rpython/typesystem.py
Log:
(arigo, fijal) - Added external function interface. Needs some simplifications and additions.
Added: pypy/dist/pypy/rpython/extfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/extfunc.py Fri Jan 12 12:09:26 2007
@@ -0,0 +1,26 @@
+
+from pypy.rpython.extregistry import ExtRegistryEntry
+from pypy.rpython.lltypesystem.lltype import typeOf
+
+class ExtFuncEntry(ExtRegistryEntry):
+ def compute_result_annotation(self, *args_s):
+ assert len(args_s) == len(self.signature_args),\
+ "Argument number mismatch"
+ for arg, expected in zip(args_s, self.signature_args):
+ assert expected.contains(arg)
+ return self.signature_result
+
+ def specialize_call(self, hop):
+ rtyper = hop.rtyper
+ args_r = [rtyper.getrepr(s_arg) for s_arg in self.signature_args]
+ args_ll = [r_arg.lowleveltype for r_arg in args_r]
+ r_result = rtyper.getrepr(self.signature_result)
+ ll_result = r_result.lowleveltype
+ name = getattr(self, 'name', None) or self.instance.__name__
+ obj = rtyper.type_system.getexternalcallable(args_ll, ll_result, name,
+ _entry=self, _callable=self.instance)
+ vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
+ hop.exception_is_here()
+ return hop.genop('direct_call', vlist, r_result)
+
+#def register_
Added: pypy/dist/pypy/rpython/test/test_extfunc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_extfunc.py Fri Jan 12 12:09:26 2007
@@ -0,0 +1,34 @@
+
+from pypy.rpython.extfunc import ExtFuncEntry
+from pypy.annotation import model as annmodel
+from pypy.annotation.annrpython import RPythonAnnotator
+from pypy.annotation.policy import AnnotatorPolicy
+from pypy.rpython.test.test_llinterp import interpret
+
+def b(x):
+ return eval("x+40")
+
+class BTestFuncEntry(ExtFuncEntry):
+ _about_ = b
+ name = 'b'
+ signature_args = [annmodel.SomeInteger()]
+ signature_result = annmodel.SomeInteger()
+
+def test_annotation_b():
+ def f():
+ return b(1)
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeInteger)
+
+def test_rtyping_b():
+ def f():
+ return b(2)
+
+ res = interpret(f, [])
+ assert res == 42
+
+
Modified: pypy/dist/pypy/rpython/typesystem.py
==============================================================================
--- pypy/dist/pypy/rpython/typesystem.py (original)
+++ pypy/dist/pypy/rpython/typesystem.py Fri Jan 12 12:09:26 2007
@@ -21,7 +21,8 @@
except ImportError:
return None
if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist',
- 'rslice', 'rdict', 'rrange', 'rstr', 'll_str', 'exceptiondata'):
+ 'rslice', 'rdict', 'rrange', 'rstr',
+ 'll_str', 'exceptiondata'):
mod = load(name)
if mod is not None:
setattr(self, name, mod)
@@ -60,6 +61,12 @@
else:
return constr(FT, graph.name, graph = graph)
+ def getexternalcallable(self, ll_args, ll_result, name, **kwds):
+ typ, constr = self.callable_trait
+
+ FT = typ(ll_args, ll_result)
+ return constr(FT, name, **kwds)
+
def getconcretetype(self, v):
"""Helper called by getcallable() to get the conrete type of a variable
in a graph."""
From antocuni at codespeak.net Fri Jan 12 12:12:38 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 12:12:38 +0100 (CET)
Subject: [pypy-svn] r36549 - pypy/dist/pypy/translator/cli/test
Message-ID: <20070112111238.BC9AE10078@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 12:12:37 2007
New Revision: 36549
Modified:
pypy/dist/pypy/translator/cli/test/test_dict.py
Log:
this test passes now.
Modified: pypy/dist/pypy/translator/cli/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_dict.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_dict.py Fri Jan 12 12:12:37 2007
@@ -33,8 +33,6 @@
py.test.skip("Iteration over empty dict is not supported, yet")
class TestCliConstantDict(CliTest, BaseTestRconstantdict):
- def test_constant_r_dict(self):
- py.test.skip('r_dict is not supported, yet')
def test_tuple_as_key(self):
mydict = {('r',): 42}
From antocuni at codespeak.net Fri Jan 12 12:13:25 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 12:13:25 +0100 (CET)
Subject: [pypy-svn] r36550 - pypy/dist/pypy/translator/cli
Message-ID: <20070112111325.681D410078@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 12:13:21 2007
New Revision: 36550
Modified:
pypy/dist/pypy/translator/cli/function.py
Log:
We reverted to the old way to handle exception by mistake.
Modified: pypy/dist/pypy/translator/cli/function.py
==============================================================================
--- pypy/dist/pypy/translator/cli/function.py (original)
+++ pypy/dist/pypy/translator/cli/function.py Fri Jan 12 12:13:21 2007
@@ -17,7 +17,7 @@
from pypy.translator.cli.support import log
from pypy.translator.cli.ilgenerator import CLIBaseGenerator
-USE_LAST = False
+USE_LAST = True
class NativeExceptionHandler(object):
def begin_try(self):
From mwh at codespeak.net Fri Jan 12 12:23:22 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Fri, 12 Jan 2007 12:23:22 +0100 (CET)
Subject: [pypy-svn] r36552 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070112112322.45C941007A@code0.codespeak.net>
Author: mwh
Date: Fri Jan 12 12:23:21 2007
New Revision: 36552
Modified:
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
argh, niko's checkin last night conflicted with some uncommitted changes of
mine. my changes were more comprehensive but niko's were nicer, so here's
hopefuly a full merge that gets the best of both worlds.
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Fri Jan 12 12:23:21 2007
@@ -236,6 +236,10 @@
def emit(self, asm):
asm.cmpw(self.result_reg.number, self.arg_reg1.number, self.arg_reg2.number)
+class CMPWL(CMPW):
+ def emit(self, asm):
+ asm.cmpwl(self.result_reg.number, self.arg_reg1.number, self.arg_reg2.number)
+
class CMPWI(CMPInsn):
def __init__(self, info, result, args):
Insn.__init__(self)
@@ -255,6 +259,11 @@
def emit(self, asm):
asm.cmpwi(self.result_reg.number, self.arg_reg.number, self.imm.value)
+class CMPWLI(CMPW):
+ def emit(self, asm):
+ asm.cmpwli(self.result_reg.number, self.arg_reg.number, self.imm.value)
+
+
## class MTCTR(Insn):
## def __init__(self, result, args):
## Insn.__init__(self)
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Jan 12 12:23:21 2007
@@ -21,6 +21,8 @@
def emit(self, value):
self.mc.write(value)
+_PPC = RPPCAssembler
+
NSAVEDREGISTERS = 19
DEBUG_TRAP = option.trap
@@ -51,7 +53,7 @@
def load(self, insns, var):
insns.append(
- insn.Insn_GPR__IMM(RPPCAssembler.load_word,
+ insn.Insn_GPR__IMM(_PPC.load_word,
var, [self]))
def load_now(self, asm, loc):
@@ -232,14 +234,14 @@
def genop_getfield(self, fieldtoken, gv_ptr):
gv_result = Var()
self.insns.append(
- insn.Insn_GPR__GPR_IMM(RPPCAssembler.lwz,
+ insn.Insn_GPR__GPR_IMM(_PPC.lwz,
gv_result, [gv_ptr, IntConst(fieldtoken)]))
return gv_result
def genop_setfield(self, fieldtoken, gv_ptr, gv_value):
gv_result = Var()
self.insns.append(
- insn.Insn_None__GPR_GPR_IMM(RPPCAssembler.stw,
+ insn.Insn_None__GPR_GPR_IMM(_PPC.stw,
[gv_value, gv_ptr, IntConst(fieldtoken)]))
return gv_result
@@ -603,14 +605,12 @@
self.asm.addi(rSCRATCH, rFP, -newsize)
self.asm.mc = mc
- def op_int_mul(self, gv_x, gv_y):
+ def _arg_op(self, gv_arg, opcode):
gv_result = Var()
- self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.mullw,
- gv_result, [gv_x, gv_y]))
+ self.insns.append(insn.Insn_GPR__GPR(opcode, gv_result, gv_arg))
return gv_result
- def generic_int_op(self, gv_x, gv_y, commutative, opcode, opcodei):
+ def _arg_arg_op_with_imm(self, gv_x, gv_y, commutative, opcode, opcodei):
gv_result = Var()
if gv_y.fits_in_immediate():
self.insns.append(
@@ -625,32 +625,24 @@
insn.Insn_GPR__GPR_GPR(opcode,
gv_result, [gv_x, gv_y]))
return gv_result
-
- def op_int_add(self, gv_x, gv_y):
- return self.generic_int_op(gv_x, gv_y, True, RPPCAssembler.add, RPPCAssembler.addi)
-
- op_uint_add = op_int_add
-
- def op_int_sub(self, gv_x, gv_y):
- return self.generic_int_op(gv_x, gv_y, False, RPPCAssembler.sub, RPPCAssembler.subi)
-
- def op_int_xor(self, gv_x, gv_y):
- return self.generic_int_op(gv_x, gv_y, True, RPPCAssembler.xor, RPPCAssembler.xori)
-
- op_uint_xor = op_int_xor
- def op_int_and(self, gv_x, gv_y):
- return self.generic_int_op(gv_x, gv_y, True, RPPCAssembler.and_, RPPCAssembler.andix)
-
- op_uint_and = op_int_and
-
- def op_int_floordiv(self, gv_x, gv_y):
+ def _arg_arg_op(self, gv_x, gv_y, opcode):
gv_result = Var()
self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.divw,
+ insn.Insn_GPR__GPR_GPR(opcode,
gv_result, [gv_x, gv_y]))
return gv_result
+ def _arg_imm_op(self, gv_x, gv_imm, opcode):
+ gv_result = Var()
+ self.insns.append(
+ insn.Insn_GPR__GPR_IMM(opcode,
+ gv_result, [gv_x, gv_imm]))
+ return gv_result
+
+ def _identity(self, gv_arg):
+ return gv_arg
+
cmp2info = {
# bit-in-crf negated
'gt': ( 1, 0 ),
@@ -660,6 +652,7 @@
'eq': ( 2, 0 ),
'ne': ( 2, 1 ),
}
+
cmp2info_flipped = {
# bit-in-crf negated
'gt': ( 1, 1 ),
@@ -671,6 +664,7 @@
}
def _compare(self, op, gv_x, gv_y):
+ #print "op", op
gv_result = Var()
if gv_y.fits_in_immediate():
self.insns.append(
@@ -683,15 +677,67 @@
insn.CMPW(self.cmp2info[op], gv_result, [gv_x, gv_y]))
return gv_result
- def op_int_gt(self, gv_x, gv_y):
- return self._compare('gt', gv_x, gv_y)
+ def _compare_u(self, op, gv_x, gv_y):
+ gv_result = Var()
+ if gv_y.fits_in_immediate():
+ self.insns.append(
+ insn.CMPWLI(self.cmp2info[op], gv_result, [gv_x, gv_y]))
+ elif gv_x.fits_in_immediate():
+ self.insns.append(
+ insn.CMPWLI(self.cmp2info_flipped[op], gv_result, [gv_y, gv_x]))
+ else:
+ self.insns.append(
+ insn.CMPWL(self.cmp2info[op], gv_result, [gv_x, gv_y]))
+ return gv_result
+
+ def _jump(self, gv_condition, if_true, args_gv):
+ targetbuilder = self.rgenop.newbuilder()
+
+ self.insns.append(
+ insn.Jump(gv_condition, targetbuilder, if_true, args_gv))
+
+ return targetbuilder
+
+ def op_bool_not(self, gv_arg):
+ gv_result = Var()
+ self.insns.append(
+ insn.Insn_GPR__GPR_IMM(RPPCAssembler.subfi,
+ gv_result, [gv_arg, rgenop.genconst(1)]))
+ return gv_result
+
+ def op_int_is_true(self, gv_arg):
+ return self._compare('ne', gv_arg, self.rgenop.genconst(0))
+
+ def op_int_neg(self, gv_arg):
+ return self._arg_op(gv_arg, _PPC.neg)
+
+ ## op_int_neg_ovf(self, gv_arg) XXX
+
+ ## op_int_abs(self, gv_arg):
+ ## op_int_abs_ovf(self, gv_arg):
+
+ def op_int_invert(self, gv_arg):
+ return self._arg_op(gv_arg, _PPC.not_)
+
+ def op_int_add(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.add, _PPC.addi)
+
+ def op_int_sub(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.sub, _PPC.subi)
+
+ def op_int_mul(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.mullw, _PPC.mulli)
+
+ def op_int_floordiv(self, gv_x, gv_y):
+ return self._arg_arg_op(gv_x, gv_y, _PPC.divw)
+
+ ## def op_int_floordiv_zer(self, gv_x, gv_y):
+ ## def op_int_mod(self, gv_x, gv_y):
+ ## def op_int_mod_zer(self, gv_x, gv_y):
def op_int_lt(self, gv_x, gv_y):
return self._compare('lt', gv_x, gv_y)
- def op_int_ge(self, gv_x, gv_y):
- return self._compare('ge', gv_x, gv_y)
-
def op_int_le(self, gv_x, gv_y):
return self._compare('le', gv_x, gv_y)
@@ -701,42 +747,116 @@
def op_int_ne(self, gv_x, gv_y):
return self._compare('ne', gv_x, gv_y)
- def _jump(self, gv_condition, if_true, args_gv):
- targetbuilder = self.rgenop.newbuilder()
+ def op_int_gt(self, gv_x, gv_y):
+ return self._compare('gt', gv_x, gv_y)
- self.insns.append(
- insn.Jump(gv_condition, targetbuilder, if_true, args_gv))
+ def op_int_ge(self, gv_x, gv_y):
+ return self._compare('ge', gv_x, gv_y)
- return targetbuilder
+ def op_int_and(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.and_, _PPC.andi)
- def op_int_is_true(self, gv_arg):
- gv_result = Var()
- self.insns.append(
- insn.CMPWI(self.cmp2info['ne'], gv_result, [gv_arg, self.rgenop.genconst(0)]))
- return gv_result
+ def op_int_or(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.or_, _PPC.ori)
- def op_bool_not(self, gv_arg):
- gv_result = Var()
- self.insns.append(
- insn.CMPWI(self.cmp2info['eq'], gv_result, [gv_arg, self.rgenop.genconst(0)]))
- return gv_result
+ def op_int_lshift(self, gv_x, gv_y):
+ # could be messy if shift is not in 0 <= ... < 32
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.slw, _PPC.slwi)
+ ## def op_int_lshift_val(self, gv_x, gv_y):
+ def op_int_rshift(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.sraw, _PPC.srawi)
+ ## def op_int_rshift_val(self, gv_x, gv_y):
- def op_int_neg(self, gv_arg):
- gv_result = Var()
- self.insns.append(
- insn.Insn_GPR__GPR(RPPCAssembler.neg, gv_result, gv_arg))
- return gv_result
+ def op_int_xor(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.xor, _PPC.xori)
+
+ ## various int_*_ovfs
+
+ op_uint_is_true = op_int_is_true
+ op_uint_invert = op_int_invert
+
+ op_uint_add = op_int_add
+ op_uint_sub = op_int_sub
+ op_uint_mul = op_int_mul
+
+ def op_uint_floordiv(self, gv_x, gv_y):
+ return self._two_arg_op(gv_x, gv_y, _PPC.divwu)
+
+ ## def op_uint_floordiv_zer(self, gv_x, gv_y):
+ ## def op_uint_mod(self, gv_x, gv_y):
+ ## def op_uint_mod_zer(self, gv_x, gv_y):
+
+ def op_uint_lt(self, gv_x, gv_y):
+ return self._compare_u('lt', gv_x, gv_y)
+
+ def op_uint_le(self, gv_x, gv_y):
+ return self._compare_u('le', gv_x, gv_y)
+
+ def op_uint_eq(self, gv_x, gv_y):
+ return self._compare_u('eq', gv_x, gv_y)
+
+ def op_uint_ne(self, gv_x, gv_y):
+ return self._compare_u('ne', gv_x, gv_y)
+
+ def op_uint_gt(self, gv_x, gv_y):
+ return self._compare_u('gt', gv_x, gv_y)
- def identity(self, gv_x):
- return gv_x
+ def op_uint_ge(self, gv_x, gv_y):
+ return self._compare_u('ge', gv_x, gv_y)
+
+ op_uint_and = op_int_add
+ op_uint_or = op_int_or
+
+ op_uint_lshift = op_int_lshift
+ def op_uint_rshift(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.srw, _PPC.srwi)
+
+ ## def op_uint_lshift_val(self, gv_x, gv_y):
+ ## def op_uint_rshift(self, gv_x, gv_y):
+ ## def op_uint_rshift_val(self, gv_x, gv_y):
+
+ op_uint_xor = op_int_xor
+
+ # ... floats ...
+
+ # ... llongs, ullongs ...
+
+ # here we assume that booleans are always 1 or 0 and chars are
+ # always zero-padded.
+
+ op_cast_bool_to_int = _identity
+ op_cast_bool_to_uint = _identity
+ ## def op_cast_bool_to_float(self, gv_arg):
+ op_cast_char_to_int = _identity
+ op_cast_unichar_to_int = _identity
+ ## def op_cast_int_to_char(self, gv_arg):
+ ## def op_cast_int_to_unichar(self, gv_arg):
+ op_cast_int_to_uint = _identity
+ ## def op_cast_int_to_float(self, gv_arg):
+ ## def op_cast_int_to_longlong(self, gv_arg):
+ op_cast_uint_to_int = _identity
+ ## def op_cast_uint_to_float(self, gv_arg):
+ ## def op_cast_float_to_int(self, gv_arg):
+ ## def op_cast_float_to_uint(self, gv_arg):
+ ## def op_truncate_longlong_to_int(self, gv_arg):
+
+ # many pointer operations are genop_* special cases above
+
+ op_ptr_eq = op_int_eq
+ op_ptr_ne = op_int_ne
op_ptr_nonzero = op_int_is_true
- op_ptr_iszero = op_bool_not # for now
op_ptr_ne = op_int_ne
op_ptr_eq = op_int_eq
- op_cast_uint_to_int = identity
- op_cast_int_to_uint = identity
+ def op_ptr_iszero(self, gv_arg):
+ return self._compare('eq', gv_arg, self.rgenop.genconst(0))
+
+ op_cast_ptr_to_int = _identity
+ op_cast_int_to_ptr = _identity
+
+ # ... address operations ...
+
class RPPCGenOp(AbstractRGenOp):
From santagada at codespeak.net Fri Jan 12 12:43:55 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Fri, 12 Jan 2007 12:43:55 +0100 (CET)
Subject: [pypy-svn] r36553 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070112114355.C459410074@code0.codespeak.net>
Author: santagada
Date: Fri Jan 12 12:43:53 2007
New Revision: 36553
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
nodes now have lineno and other interesting stuff for tracebacks and for break
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Fri Jan 12 12:43:53 2007
@@ -4,9 +4,13 @@
from pypy.rlib.parsing.ebnfparse import Symbol, Nonterminal
class Node(object):
- # TODO Add line info for debug
-# def __init__(self, lineno = 1):
-# self.lineno = lineno
+ def init_common(self, type='', value='', lineno=0, start=0, end=0):
+ self.type = type
+ self.value = value
+ self.lineno = lineno
+ self.start = start
+ self.end = end
+
def eval(self, ctx):
raise NotImplementedError
@@ -45,7 +49,6 @@
def decision(self, ctx, op1, op2):
raise NotImplementedError
-
class BinaryLogicOp(BinaryOp):
"""super class for binary operators"""
pass
@@ -81,8 +84,8 @@
class PropertyInit(Node):
def __init__(self, name, value):
- self.namein = name
- self.value = value
+ self.nameinit = name
+ self.valueinit = value
def __repr__(self):
return "<%s : %s>"%(str(self.namein), str(self.value))
@@ -99,6 +102,7 @@
d[i] = self.items[i]
return W_Array(d)
+
class Assign(Expression):
def __init__(self, LHSExp, AssignmentExp):
self.LHSExp = LHSExp
@@ -112,6 +116,7 @@
v1.PutValue(v3, ctx)
return v3
+
class Block(Statement):
def __init__(self, nodes):
self.nodes = nodes
@@ -125,6 +130,7 @@
except ExecutionReturned, e:
return e.value
+
class Call(Expression):
def __init__(self, identifier, arglist):
self.identifier = identifier
@@ -141,11 +147,13 @@
retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.get_args(ctx)])
return retval
+
class Comma(BinaryOp):
def eval(self, ctx):
self.left.eval(ctx)
return self.right.eval(ctx)
+
class Conditional(Expression):
def __init__(self, logicalexpr, trueop, falseop):
self.logicalexpr = logicalexpr
@@ -193,13 +201,14 @@
def get_literal(self):
return self.name
+
class If(Statement):
def __init__(self, condition, thenPart=None, elsePart=None):
self.condition = condition
self.thenPart = thenPart
self.elsePart = elsePart
- def execute(self, ctx=None):
+ def execute(self, ctx):
temp = self.condition.eval(ctx)
#print "if condition = ", temp
if temp.ToBoolean():
@@ -373,11 +382,9 @@
def eval(self, ctx):
w_obj = W_Object()
- ##print "properties = ", self.properties
for property in self.properties:
- name = property.namein.get_literal()
- #print "prop name = ", name
- w_expr = property.value.eval(ctx).GetValue()
+ name = property.nameinit.get_literal()
+ w_expr = property.valueinit.eval(ctx).GetValue()
w_obj.Put(name, w_expr)
return w_obj
@@ -414,12 +421,6 @@
except ExecutionReturned, e:
return e.value
- def append_script(self, newscript):
- """copy everything from the newscript to this one"""
- self.var_decl.extend(newscript.var_decl)
- self.nodes.extend(newscript.nodes)
- self.func_decl.extend(newscript.func_decl)
-
class Semicolon(Statement):
def __init__(self, expr = None):
self.expr = expr
@@ -548,38 +549,39 @@
return x.children[1]
return None
+
def from_tree(t):
if t is None:
return None
tp = gettreeitem(t, 'type').additional_info
if tp == 'ARRAY_INIT':
- return Array(getlist(t))
+ node = Array(getlist(t))
elif tp == 'ASSIGN':
- return Assign(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Assign(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'BLOCK':
- return Block(getlist(t))
+ node = Block(getlist(t))
elif tp == 'CALL':
- return Call(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Call(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'COMMA':
- return Comma(from_tree(gettreeitem(t, '0')),from_tree(gettreeitem(t, '1')))
+ node = Comma(from_tree(gettreeitem(t, '0')),from_tree(gettreeitem(t, '1')))
elif tp == 'CONDITIONAL':
- return Conditional(from_tree(gettreeitem(t, '0')),
+ node = Conditional(from_tree(gettreeitem(t, '0')),
from_tree(gettreeitem(t, '1')),
from_tree(gettreeitem(t, '2')))
elif tp == 'DOT':
- return Dot(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Dot(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'EQ':
- return Eq(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Eq(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'OR':
- return Or(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Or(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'AND':
- return And(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = And(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'FOR':
setup = from_tree(gettreeitem(t, 'setup'))
condition = from_tree(gettreeitem(t, 'condition'))
update = from_tree(gettreeitem(t, 'update'))
body = from_tree(gettreeitem(t, 'body'))
- return For(setup, condition, update, body)
+ node = For(setup, condition, update, body)
elif tp == 'FUNCTION':
namesimb = gettreeitem(t, 'name')
name = None
@@ -591,15 +593,15 @@
else:
params = gettreeitem(t, 'params').additional_info.split(',')
f = Function(name, params, body)
- return f
+ node = f
elif tp == 'GROUP':
- return Group(from_tree(gettreeitem(t, '0')))
+ node = Group(from_tree(gettreeitem(t, '0')))
elif tp == 'GE':
- return Ge(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Ge(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'GT':
- return Gt(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Gt(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'IDENTIFIER':
- return Identifier(gettreeitem(t, 'value').additional_info, from_tree(gettreeitem(t, 'initializer')))
+ node = Identifier(gettreeitem(t, 'value').additional_info, from_tree(gettreeitem(t, 'initializer')))
elif tp == 'IF':
condition = from_tree(gettreeitem(t, 'condition'))
thenPart = gettreeitem(t, 'thenPart')
@@ -613,35 +615,35 @@
elsePart = from_tree(elsePart)
else:
elsePart = Undefined()
- return If(condition,thenPart,elsePart)
+ node = If(condition,thenPart,elsePart)
elif tp == 'IN':
- return In(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = In(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'INCREMENT':
- return Increment(from_tree(gettreeitem(t, '0')))
+ node = Increment(from_tree(gettreeitem(t, '0')))
elif tp == 'INDEX':
- return Index(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Index(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'LIST':
- return List(getlist(t))
+ node = List(getlist(t))
elif tp == 'LE':
- return Le(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Le(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'LT':
- return Lt(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Lt(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'MINUS':
- return Minus(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Minus(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NE':
- return Ne(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Ne(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NEW':
- return New(gettreeitem(gettreeitem(t, '0'),'value').additional_info)
+ node = New(gettreeitem(gettreeitem(t, '0'),'value').additional_info)
elif tp == 'NUMBER':
- return Number(float(gettreeitem(t, 'value').additional_info))
+ node = Number(float(gettreeitem(t, 'value').additional_info))
elif tp == 'OBJECT_INIT':
- return ObjectInit(getlist(t))
+ node = ObjectInit(getlist(t))
elif tp == 'PLUS':
- return Plus(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = Plus(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'PROPERTY_INIT':
- return PropertyInit(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
+ node = PropertyInit(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'RETURN':
- return Return(from_tree(gettreeitem(t, 'value')))
+ node = Return(from_tree(gettreeitem(t, 'value')))
elif tp == 'SCRIPT':
f = gettreeitem(t, 'funDecls')
# print f.symbol
@@ -661,18 +663,18 @@
else:
var_decl = []
- return Script(getlist(t), var_decl, func_decl)
+ node = Script(getlist(t), var_decl, func_decl)
elif tp == 'SEMICOLON':
expr = gettreeitem(t, 'expression')
if isinstance(expr, Symbol):
- return Semicolon()
- return Semicolon(from_tree(expr))
+ node = Semicolon()
+ node = Semicolon(from_tree(expr))
elif tp == 'STRING':
- return String(gettreeitem(t, 'value').additional_info)
+ node = String(gettreeitem(t, 'value').additional_info)
elif tp == 'THIS':
- return Identifier(gettreeitem(t, 'value').additional_info)
+ node = Identifier(gettreeitem(t, 'value').additional_info)
elif tp == 'THROW':
- return Throw(from_tree(gettreeitem(t, 'exception')))
+ node = Throw(from_tree(gettreeitem(t, 'exception')))
elif tp == 'TRY':
finallyblock = None
catchblock = None
@@ -685,18 +687,38 @@
#multiple catch clauses is a spidermonkey extension
catchblock = from_tree(gettreeitem(catch, 'block'))
catchparam = gettreeitem(catch, 'varName').additional_info
- return Try(from_tree(gettreeitem(t, 'tryBlock')), catchblock, finallyblock, catchparam)
+ node = Try(from_tree(gettreeitem(t, 'tryBlock')), catchblock, finallyblock, catchparam)
elif tp == 'VAR':
- return Vars(getlist(t))
+ node = Vars(getlist(t))
elif tp == 'WHILE':
body = from_tree(gettreeitem(t, 'body'))
condition = from_tree(gettreeitem(t, 'condition'))
- return While(condition, body)
+ node = While(condition, body)
elif tp == 'TRUE':
- return Boolean(True)
+ node = Boolean(True)
elif tp == 'FALSE':
- return Boolean(False)
+ node = Boolean(False)
elif tp == 'NOT':
- return Not(from_tree(gettreeitem(t, '0')))
+ node = Not(from_tree(gettreeitem(t, '0')))
else:
raise NotImplementedError("Dont know how to handler %s" % tp)
+
+ if tp == 'SCRIPT':
+ start = 0
+ end = 0
+ else:
+ start = int(gettreeitem(t, 'start').additional_info)
+ end = int(gettreeitem(t, 'end').additional_info)
+
+ if tp == 'SCRIPT' or tp == 'RETURN':
+ value = gettreeitem(t, 'type')
+ else:
+ value = gettreeitem(t, 'value').additional_info
+
+
+ print tp
+ node.init_common(gettreeitem(t, 'type').additional_info, value,
+ int(gettreeitem(t, 'lineno').additional_info), start, end)
+ return node
+
+
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Fri Jan 12 12:43:53 2007
@@ -326,6 +326,11 @@
def test_break(self):
py.test.skip(" TODO: needed for mozilla test suite")
+ self.assert_prints("""
+ while(1){
+ break;
+ }
+ print('out')""", ["out"])
def test_typeof(self):
py.test.skip(" TODO: needed for mozilla test suite")
@@ -369,10 +374,7 @@
if ( gc == undefined ) {
print('undef');
}
- """
- x = "if ( ! x ) { "
- x = "var x = false;"
-
+ """
x = "Math.abs(actual-expect) < 0.0000001 ) {"
x = """if ( isNaN( t ) ){
return ( Number.NaN );"""
From ericvrp at codespeak.net Fri Jan 12 12:49:14 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 12 Jan 2007 12:49:14 +0100 (CET)
Subject: [pypy-svn] r36554 - in pypy/dist/pypy/translator/llvm: . test
Message-ID: <20070112114914.A2EE210077@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 12 12:49:04 2007
New Revision: 36554
Modified:
pypy/dist/pypy/translator/llvm/buildllvm.py
pypy/dist/pypy/translator/llvm/externs2ll.py
pypy/dist/pypy/translator/llvm/test/runtest.py
pypy/dist/pypy/translator/llvm/test/test_lltype.py
pypy/dist/pypy/translator/llvm/test/test_rtagged.py
Log:
make some translator/llvm aware that they require gcc3.
Modified: pypy/dist/pypy/translator/llvm/buildllvm.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/buildllvm.py (original)
+++ pypy/dist/pypy/translator/llvm/buildllvm.py Fri Jan 12 12:49:04 2007
@@ -15,14 +15,14 @@
return False
return True
-def llvm_version():
- v = os.popen('llvm-as -version 2>&1').read()
+def exe_version(exe):
+ v = os.popen(exe + ' -version 2>&1').read()
v = ''.join([c for c in v if c.isdigit()])
v = int(v) / 10.0
return v
-def llvm_gcc_version():
- v = os.popen('llvm-gcc --version 2>&1').read()
+def exe_version2(exe):
+ v = os.popen(exe + ' --version 2>&1').read()
i = v.index(')')
v = v[i+2:].split()[0].split('.')
major, minor = v[0], ''.join([c for c in v[1] if c.isdigit()])
Modified: pypy/dist/pypy/translator/llvm/externs2ll.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/externs2ll.py (original)
+++ pypy/dist/pypy/translator/llvm/externs2ll.py Fri Jan 12 12:49:04 2007
@@ -7,7 +7,7 @@
from pypy.rpython.rmodel import inputconst
from pypy.rpython.lltypesystem import lltype
from pypy.translator.llvm.codewriter import DEFAULT_CCONV
-from pypy.translator.llvm.buildllvm import llvm_gcc_version
+from pypy.translator.llvm.buildllvm import exe_version2
from pypy.tool.udir import udir
@@ -42,7 +42,7 @@
global _llvm_gcc_version
if not _llvm_gcc_version:
- _llvm_gcc_version = llvm_gcc_version()
+ _llvm_gcc_version = exe_version2('llvm-gcc')
if _llvm_gcc_version < 4.0:
emit_llvm = ''
else:
Modified: pypy/dist/pypy/translator/llvm/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/runtest.py (original)
+++ pypy/dist/pypy/translator/llvm/test/runtest.py Fri Jan 12 12:49:04 2007
@@ -1,7 +1,7 @@
import py
from pypy.tool import isolate
from pypy.translator.llvm.genllvm import genllvm_compile
-from pypy.translator.llvm.buildllvm import llvm_is_on_path, llvm_version
+from pypy.translator.llvm.buildllvm import llvm_is_on_path, exe_version, exe_version2
optimize_tests = False
MINIMUM_LLVM_VERSION = 1.7
MAXIMUM_LLVM_VERSION = 2.0
@@ -33,7 +33,7 @@
if not llvm_is_on_path():
py.test.skip("could not find one of llvm-as or llvm-gcc")
return False
- v = llvm_version()
+ v = exe_version('llvm-as')
if v < MINIMUM_LLVM_VERSION:
py.test.skip("llvm version not up-to-date (found "
"%.1f, should be >= %.1f)" % (v, MINIMUM_LLVM_VERSION))
@@ -44,6 +44,13 @@
return False
return True
+def gcc3_test():
+ v = exe_version2('gcc')
+ if int(v) != 3:
+ py.test.skip("test required gcc version 3 (found version %.1f)" % v)
+ return False
+ return True
+
def compile_test(function, annotation, isolate=True, **kwds):
" returns module and compiled function "
if llvm_test():
Modified: pypy/dist/pypy/translator/llvm/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_lltype.py (original)
+++ pypy/dist/pypy/translator/llvm/test/test_lltype.py Fri Jan 12 12:49:04 2007
@@ -240,6 +240,7 @@
assert f() == floats_fn()
def test_fixedsizearray():
+ gcc3_test()
S = Struct("s", ('v', Signed))
A7 = FixedSizeArray(Signed, 7)
A3 = FixedSizeArray(S, 3)
@@ -268,6 +269,7 @@
assert fn() == 607
def test_recursivearray():
+ gcc3_test()
A = ForwardReference()
A.become(FixedSizeArray(Struct("S", ('a', Ptr(A))), 5))
TREE = GcStruct("TREE", ("root", A), ("other", A))
@@ -298,6 +300,7 @@
fn()
def test_call_with_fixedsizearray():
+ gcc3_test()
A = FixedSizeArray(Struct('s1', ('x', Signed)), 5)
S = GcStruct('s', ('a', Ptr(A)))
a = malloc(A, immortal=True)
@@ -313,6 +316,7 @@
assert res == 123
def test_more_prebuilt_arrays():
+ gcc3_test()
A = FixedSizeArray(Struct('s1', ('x', Signed)), 5)
S = GcStruct('s', ('a1', Ptr(A)), ('a2', A))
s = malloc(S, zero=True)
@@ -332,6 +336,7 @@
assert res == 60
def test_fnptr_with_fixedsizearray():
+ gcc3_test()
A = ForwardReference()
F = FuncType([Ptr(A)], Signed)
A.become(FixedSizeArray(Struct('s1', ('f', Ptr(F)), ('n', Signed)), 5))
Modified: pypy/dist/pypy/translator/llvm/test/test_rtagged.py
==============================================================================
--- pypy/dist/pypy/translator/llvm/test/test_rtagged.py (original)
+++ pypy/dist/pypy/translator/llvm/test/test_rtagged.py Fri Jan 12 12:49:04 2007
@@ -68,6 +68,7 @@
def test_tagged_boehm():
runtest.llvm_test()
+ runtest.gcc3_test()
t = Translation(entry_point, standalone=True, gc='boehm')
try:
exename = t.compile_llvm()
From fijal at codespeak.net Fri Jan 12 12:53:22 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 12:53:22 +0100 (CET)
Subject: [pypy-svn] r36555 - in pypy/dist/pypy/rpython: . test
Message-ID: <20070112115322.C239E1007A@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 12:53:03 2007
New Revision: 36555
Modified:
pypy/dist/pypy/rpython/extfunc.py
pypy/dist/pypy/rpython/test/test_extfunc.py
Log:
(arigo, cfbolz, fijal) - Add possibility to create different implementations for different typesystems.
Modified: pypy/dist/pypy/rpython/extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunc.py (original)
+++ pypy/dist/pypy/rpython/extfunc.py Fri Jan 12 12:53:03 2007
@@ -1,6 +1,7 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.lltypesystem.lltype import typeOf
+from pypy.objspace.flow.model import Constant
class ExtFuncEntry(ExtRegistryEntry):
def compute_result_annotation(self, *args_s):
@@ -8,6 +9,16 @@
"Argument number mismatch"
for arg, expected in zip(args_s, self.signature_args):
assert expected.contains(arg)
+
+ for type_system in ['lltype', 'ootype']:
+ impl = getattr(self, type_system + 'impl', None)
+ if impl:
+ key = impl.im_func
+ pbc = self.bookkeeper.immutablevalue(impl.im_func)
+ s_result = self.bookkeeper.emulate_pbc_call(key, pbc,
+ self.signature_args)
+ assert self.signature_result.contains(s_result)
+
return self.signature_result
def specialize_call(self, hop):
@@ -17,10 +28,17 @@
r_result = rtyper.getrepr(self.signature_result)
ll_result = r_result.lowleveltype
name = getattr(self, 'name', None) or self.instance.__name__
- obj = rtyper.type_system.getexternalcallable(args_ll, ll_result, name,
- _entry=self, _callable=self.instance)
- vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
- hop.exception_is_here()
- return hop.genop('direct_call', vlist, r_result)
-
-#def register_
+ method_name = rtyper.type_system.name[:2] + 'typeimpl'
+ impl = getattr(self, method_name, None)
+ if impl:
+ hop2 = hop.copy()
+ v = Constant(impl.im_func)
+ bookkeeper = rtyper.annotator.bookkeeper
+ hop2.v_s_insertfirstarg(v, bookkeeper.immutablevalue(impl.im_func))
+ return hop2.dispatch()
+ else:
+ obj = rtyper.type_system.getexternalcallable(args_ll, ll_result,
+ name, _entry=self, _callable=self.instance)
+ vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
+ hop.exception_is_here()
+ return hop.genop('direct_call', vlist, r_result)
Modified: pypy/dist/pypy/rpython/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_extfunc.py (original)
+++ pypy/dist/pypy/rpython/test/test_extfunc.py Fri Jan 12 12:53:03 2007
@@ -31,4 +31,21 @@
res = interpret(f, [])
assert res == 42
-
+def c(y, x):
+ yyy
+
+class CTestFuncEntry(ExtFuncEntry):
+ _about_ = c
+ name = 'ccc'
+ signature_args = [annmodel.SomeInteger()] * 2
+ signature_result = annmodel.SomeInteger()
+
+ def lltypeimpl(y, x):
+ return y + x
+
+def test_interp_c():
+ def f():
+ return c(3, 4)
+
+ res = interpret(f, [])
+ assert res == 7
From cfbolz at codespeak.net Fri Jan 12 12:56:01 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 12:56:01 +0100 (CET)
Subject: [pypy-svn] r36556 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070112115601.516361007E@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 12:55:55 2007
New Revision: 36556
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
Log:
(all): oops, somewhat late: planning for today
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt Fri Jan 12 12:55:55 2007
@@ -3,7 +3,6 @@
* Antonio
* Leonardo
- * Holger
* Guido
* Maciek
* Armin
@@ -21,6 +20,7 @@
later
-----
+ * Holger
Tasks
@@ -32,7 +32,8 @@
* "virtual frames" (Samuele, Arre): funfunfun. basic test is working,
manually written virtualizable structs can be change within the jit-generated
code and the changes are seen from outside.
- started a new test, refactoring necessary. IN-PROGRESS
+ some more tests pass. easy part of the hard part is about to start.
+ IN-PROGRESS
- write a small interpreter that shows the performance problems without having
to use the full pypy
@@ -42,7 +43,7 @@
* have register allocation: IN-PROGRESS: redesigned the
backend interface a bit, adapted all the backends to the changes. Michael
started completing the PPC backend, but is getting annoyed
- Armin started working on register allocation on i386
+ Armin did more work on register allocation on i386
@@ -52,16 +53,17 @@
* polish the code and documentation of the py lib, and eventually
release it MORE PROGRESS
-* integrate api-doc and source-viewer on the py-lib web-page IN-PROGRESS
- (Guido, Holger)
+* integrate api-doc and source-viewer on the py-lib web-page
+ SLOW PROGRESS on rewrite the page generation to produce HTML directly
+ (Guido, Maciek)
* use source-viewer on more code? pypy? IN-PROGRESS
-* debian packaging for the py-lib: HUGE PROGRESS (Alexandre, Sylvain)
+* debian packaging for the py-lib: DONE (need to port changes)
* (provide code search facility)
-* detailed (and growing) TODO list in py/documentation/TODO.txt
+* detailed (and shrinking) TODO list in py/documentation/TODO.txt
interpreter prototypes
@@ -79,8 +81,7 @@
Integration and Configuration
-----------------------------
-* actually use the build tool during the sprint (Michael, Carl Friedrich): DONE
- WITH BUGS
+* actually use the build tool during the sprint: FIXED SOME SMALL THINGS
* think about py-lib and pypy debian packaging
@@ -95,20 +96,38 @@
* progress on the JavaScript interpreter (Leonardo, Maciek): IN-PROGRESS,
the JS intepreter translates. There is now an interactive interpreter.
+ for loops, enough parsing machinery for EcmaTest
-* Java backend (Niko, Antonio): lot of random problems fixed, test_class runs
- completely. test_pbc is next!
+* Java backend: lot of random problems fixed, test_class, test_pbc, test_list,
+ test_dict run completely. external functions, test_rdict are next!
* investigate why the annotator fails when doing --faassen with gencli?!
- (Anto, general wizards around)
+ (Anto, general wizards around) (same bug than in the build tool)
-* discuss refinement interface for external functions
+* discuss refinement interface for external functions SOME PROGRESS: annotation
+ part is mostly done (Maciek, Michael)
* (make py-lib run on pypy-c) PROGRESS: the compiler problems are fixed
* "shadow tracking" (Carl Friedrich, Samuele), DONE
-* progress on the LLVM JIT code generator (Eric, Armin)
+* progress on the LLVM JIT code generator. PROGRESS: fixing operations of the
+ LLVM codegen (Eric, Armin)
+
+* progress on the translation of the parser branch (Adrien remotely, Sylvain,
+ Michael around)
+
+* add an option to translate.py to give a name to the executable (Alexandre,
+ Carl Friedrich)
+
+
+Report outline writing
+----------------------
+
+ * Guido, Carl Friedrich, Alexandre: WP13
+ * Guido, Carl Friedrich, Maciek: WP2
+ * Arre, Maciek, Armin, Anto: WP12
+ * Michael, Samuele, Carl Friedrich?: WP6
Discussions during the sprint
@@ -125,3 +144,5 @@
* pypy and py-lib debian packaging discussion: thursday morning 11am
(Michael, Alexandre, Carl Friedrich, Sylvain)
+
+* there is the idea of doing a game evening friday
From afayolle at codespeak.net Fri Jan 12 13:14:04 2007
From: afayolle at codespeak.net (afayolle at codespeak.net)
Date: Fri, 12 Jan 2007 13:14:04 +0100 (CET)
Subject: [pypy-svn] r36557 - in pypy/dist/pypy: config translator/goal
Message-ID: <20070112121404.348FA1007C@code0.codespeak.net>
Author: afayolle
Date: Fri Jan 12 13:14:02 2007
New Revision: 36557
Modified:
pypy/dist/pypy/config/translationoption.py
pypy/dist/pypy/translator/goal/translate.py
Log:
added an --output=FILENAME option, to override the name of a translated target
Modified: pypy/dist/pypy/config/translationoption.py
==============================================================================
--- pypy/dist/pypy/config/translationoption.py (original)
+++ pypy/dist/pypy/config/translationoption.py Fri Jan 12 13:14:02 2007
@@ -57,7 +57,8 @@
ArbitraryOption("instrumentctl", "internal",
default=None),
-
+ StrOption("output", "Output file name", cmdline="--output"),
+
# portability options
BoolOption("vanilla",
"Try to be as portable as possible, which is not much",
Modified: pypy/dist/pypy/translator/goal/translate.py
==============================================================================
--- pypy/dist/pypy/translator/goal/translate.py (original)
+++ pypy/dist/pypy/translator/goal/translate.py Fri Jan 12 13:14:02 2007
@@ -76,6 +76,7 @@
'translation.cc': None,
'translation.profopt': None,
+ 'translation.output': None,
'translation.debug_transform': False,
}
@@ -186,7 +187,6 @@
def main():
targetspec_dic, translateconfig, config, args = parse_options_and_load_target()
-
from pypy.translator import translator
from pypy.translator import driver
from pypy.translator.tool.pdbplus import PdbPlusShow
@@ -259,7 +259,9 @@
log_config(config.translation, "translation configuration")
pdb_plus_show.expose({'drv': drv, 'prof': prof})
- if drv.exe_name is None and '__name__' in targetspec_dic:
+ if config.translation.output:
+ drv.exe_name = config.translation.output
+ elif drv.exe_name is None and '__name__' in targetspec_dic:
drv.exe_name = targetspec_dic['__name__'] + '-%(backend)s'
goals = translateconfig.goals
From niko at codespeak.net Fri Jan 12 13:25:04 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Fri, 12 Jan 2007 13:25:04 +0100 (CET)
Subject: [pypy-svn] r36558 - in pypy/dist/pypy/translator: cli/test jvm
jvm/src/pypy jvm/test oosupport/test_template
Message-ID: <20070112122504.CA5F41007C@code0.codespeak.net>
Author: niko
Date: Fri Jan 12 13:25:03 2007
New Revision: 36558
Added:
pypy/dist/pypy/translator/jvm/test/test_string.py
pypy/dist/pypy/translator/oosupport/test_template/string.py
Modified:
pypy/dist/pypy/translator/cli/test/test_dict.py
pypy/dist/pypy/translator/cli/test/test_string.py
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/genjvm.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
pypy/dist/pypy/translator/jvm/typesystem.py
pypy/dist/pypy/translator/oosupport/test_template/dict.py
Log:
(antocuni, niko)
add support for most of test_string, and refactor the cli test_dict
so it doesn't duplicate info
Modified: pypy/dist/pypy/translator/cli/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_dict.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_dict.py Fri Jan 12 13:25:03 2007
@@ -1,41 +1,18 @@
import py
from pypy.translator.cli.test.runtest import CliTest
-from pypy.rpython.test.test_rdict import TestOOtype as _TestOOtype
-from pypy.rpython.test.test_remptydict import BaseTestRemptydict
-from pypy.rpython.test.test_rconstantdict import BaseTestRconstantdict
-
-class TestCliDict(CliTest, _TestOOtype):
- def test_dict_of_void(self):
- class A: pass
- def f():
- d2 = {A(): None, A(): None}
- return len(d2)
- res = self.interpret(f, [])
- assert res == 2
-
- def test_dict_of_void_iter(self):
- def f():
- d = {1: None, 2: None, 3: None}
- total = 0
- for key, value in d.iteritems():
- total += key
- return total
- assert self.interpret(f, []) == 6
+import pypy.translator.oosupport.test_template.dict as oodict
+class TestCliDict(CliTest, oodict.BaseTestDict):
def test_dict_of_dict(self):
py.test.skip("CLI doesn't support recursive dicts")
def test_recursive(self):
py.test.skip("CLI doesn't support recursive dicts")
-class TestCliEmptyDict(CliTest, BaseTestRemptydict):
+
+class TestCliEmptyDict(CliTest, oodict.BaseTestEmptyDict):
def test_iterate_over_empty_dict(self):
py.test.skip("Iteration over empty dict is not supported, yet")
-class TestCliConstantDict(CliTest, BaseTestRconstantdict):
-
- def test_tuple_as_key(self):
- mydict = {('r',): 42}
- def fn(ch):
- return mydict[(ch,)]
- assert self.interpret(fn, ['r']) == 42
+class TestCliConstantDict(CliTest, oodict.BaseTestConstantDict):
+ pass
Modified: pypy/dist/pypy/translator/cli/test/test_string.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_string.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_string.py Fri Jan 12 13:25:03 2007
@@ -1,25 +1,11 @@
import py
from pypy.translator.cli.test.runtest import CliTest
-from pypy.rpython.test.test_rstr import BaseTestRstr
+import pypy.translator.oosupport.test_template.string as oostring
-class TestCliString(CliTest, BaseTestRstr):
+class TestCliString(CliTest, oostring.BaseTestString):
EMPTY_STRING_HASH = 0
- def test_char_isxxx(self):
- def fn(s):
- return (s.isspace() |
- s.isdigit() << 1 |
- s.isalpha() << 2 |
- s.isalnum() << 3 |
- s.isupper() << 4 |
- s.islower() << 5)
- # need to start from 1, because we cannot pass '\x00' as a command line parameter
- for i in range(1, 128):
- ch = chr(i)
- res = self.interpret(fn, [ch])
- assert res == fn(ch)
-
def test_unichar_const(self):
py.test.skip("CLI interpret doesn't support unicode for input arguments")
test_unichar_eq = test_unichar_const
@@ -30,25 +16,9 @@
py.test.skip("CLI doens't support backquotes inside string literals")
test_lower = test_upper
- def test_replace_TyperError(self):
- pass # it doesn't make sense here
-
def test_hlstr(self):
py.test.skip("CLI tests can't have string as input arguments")
- def test_hash_value(self):
- # make that hash are computed by value and not by reference
- def fn(x, y):
- s1 = ''.join([x, 'e', 'l', 'l', 'o'])
- s2 = ''.join([y, 'e', 'l', 'l', 'o'])
- return (hash(s1) == hash(s2)) and (s1 is not s2)
- assert self.interpret(fn, ['h', 'h']) == True
-
- def test_int_formatting(self):
- def fn(answer):
- return 'the answer is %s' % answer
- assert self.ll_to_string(self.interpret(fn, [42])) == 'the answer is 42'
-
def test_getitem_exc(self):
py.test.skip('fixme!')
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Fri Jan 12 13:25:03 2007
@@ -3,7 +3,7 @@
from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.typesystem import \
jInt, jVoid, jStringBuilder, jString, jPyPy, jChar, jArrayList, jObject, \
- jBool, jHashMap, jPyPyDictItemsIterator, Generifier
+ jBool, jHashMap, jPyPyDictItemsIterator, Generifier, jCharSequence
# ______________________________________________________________________
# Mapping of built-in OOTypes to JVM types
@@ -94,6 +94,27 @@
(ootype.String.__class__, "ll_stritem_nonneg"):
jvmgen.Method.v(jString, "charAt", (jInt,), jChar),
+ (ootype.String.__class__, "ll_startswith"):
+ jvmgen.Method.v(jString, "startsWith", (jString,), jBool),
+
+ (ootype.String.__class__, "ll_endswith"):
+ jvmgen.Method.v(jString, "endsWith", (jString,), jBool),
+
+ (ootype.String.__class__, "ll_strcmp"):
+ jvmgen.Method.v(jString, "compareTo", (jString,), jInt),
+
+ (ootype.String.__class__, "ll_upper"):
+ jvmgen.Method.v(jString, "toUpperCase", (), jString),
+
+ (ootype.String.__class__, "ll_lower"):
+ jvmgen.Method.v(jString, "toLowerCase", (), jString),
+
+ (ootype.String.__class__, "ll_contains"):
+ jvmgen.Method.v(jString, "contains", (jCharSequence,), jBool),
+
+ (ootype.String.__class__, "ll_replace_chr_chr"):
+ jvmgen.Method.v(jString, "replace", (jChar, jChar), jString),
+
(ootype.Dict, "ll_set"):
jvmgen.Method.v(jHashMap, "put", (jObject, jObject), jObject),
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Fri Jan 12 13:25:03 2007
@@ -600,6 +600,8 @@
def escape(char):
if char == '"': return r'\"'
if char == '\n': return r'\n'
+ if char == "\\": return r'\\'
+ if ord(char) > 127: return r'\u%04x' % ord(char)
return char
res = ('"' +
"".join(escape(c) for c in str) +
@@ -1072,7 +1074,7 @@
not_equals = lambda self: self._compare_op(IF_ICMPNE)
less_than = lambda self: self._compare_op(IF_ICMPLT)
greater_than = lambda self: self._compare_op(IF_ICMPGT)
- less_equals = lambda self: self._compare_op(IF_ICMPLT)
+ less_equals = lambda self: self._compare_op(IF_ICMPLE)
greater_equals = lambda self: self._compare_op(IF_ICMPGE)
def _uint_compare_op(self, cmpopcode):
Modified: pypy/dist/pypy/translator/jvm/genjvm.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/genjvm.py (original)
+++ pypy/dist/pypy/translator/jvm/genjvm.py Fri Jan 12 13:25:03 2007
@@ -15,6 +15,7 @@
from pypy.translator.jvm.log import log
from pypy.translator.jvm.node import EntryPoint, Function
from pypy.translator.jvm.opcodes import opcodes
+from pypy.rpython.ootypesystem import ootype
from pypy.translator.jvm.constant import \
JVMConstantGenerator, JVMStaticMethodConst
@@ -122,12 +123,18 @@
print "Invoking jasmin on %s" % self.jasmin_files
self._invoke(jascmd+list(self.jasmin_files), False)
+ print "... completed!"
self.compiled = True
self._compile_helper(('DictItemsIterator',
'PyPy',
'ExceptionWrapper'))
+ def _make_str(self, a):
+ if isinstance(a, ootype._string):
+ return a._str
+ return str(a)
+
def execute(self, args):
"""
Executes the compiled sources in a separate process. Returns the
@@ -135,12 +142,14 @@
and will be converted to strings.
"""
assert self.compiled
- strargs = [str(a) for a in args]
+ strargs = [self._make_str(a) for a in args]
cmd = [getoption('java'),
'-cp',
str(self.javadir),
self.package+".Main"] + strargs
+ print "Invoking java to run the code"
stdout, stderr = self._invoke(cmd, True)
+ print "...done!"
sys.stderr.write(stderr)
return stdout
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Fri Jan 12 13:25:03 2007
@@ -82,7 +82,9 @@
lltype.UnsignedLongLong:jvmgen.PYPYSTRTOULONG,
ootype.Bool:jvmgen.PYPYSTRTOBOOL,
ootype.Float:jvmgen.PYPYSTRTODOUBLE,
- ootype.Char:jvmgen.PYPYSTRTOCHAR
+ ootype.Char:jvmgen.PYPYSTRTOCHAR,
+ ootype.UniChar:jvmgen.PYPYSTRTOCHAR,
+ ootype.String:None
}
def render(self, gen):
@@ -102,7 +104,8 @@
gen.load_jvm_var(jStringArray, 0)
gen.emit(jvmgen.ICONST, i)
gen.load_from_array(jString)
- gen.emit(self._type_conversion_methods[arg.concretetype])
+ conv = self._type_conversion_methods[arg.concretetype]
+ if conv: gen.emit(conv)
else:
# Convert the array of strings to a List as the
# python method expects
Modified: pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java Fri Jan 12 13:25:03 2007
@@ -268,6 +268,107 @@
return str1 + str2;
}
+ public static int ll_find(String haystack, String needle, int start, int end) {
+ // if it is impossible for the needle to occur:
+ // this deals w/ a disparity in how java and python handle when needle=""
+ if (start > haystack.length())
+ return -1;
+
+ int res = haystack.indexOf(needle, start);
+ System.err.println("haystack="+haystack+" needle="+needle+" start="+start+
+ " end="+end+" res="+res);
+ if (res + needle.length() > end)
+ return -1;
+ return res;
+ }
+
+ public static int ll_rfind(String haystack, String needle, int start, int end) {
+ int res = haystack.lastIndexOf(needle, end-1);
+ System.err.println("haystack="+haystack+" needle="+needle+" start="+start+
+ " end="+end+" res="+res);
+ if (res >= start)
+ return res;
+ return -1;
+ }
+
+ public static int ll_count(String haystack, String needle, int start, int end) {
+ haystack = haystack.substring(start, end);
+
+ if (needle.length() == 0) {
+ return haystack.length()+1;
+ }
+
+ int cnt = 0;
+ int lastidx = 0, idx = -1;
+ while ((idx = haystack.indexOf(needle, lastidx)) != -1) {
+ cnt++;
+ lastidx = idx + needle.length(); // avoid overlapping occurrences
+ }
+ return cnt;
+ }
+
+ public static int ll_find_char(String haystack, char needle, int start, int end) {
+ // see ll_find
+ if (start > haystack.length())
+ return -1;
+
+ int res = haystack.indexOf(needle, start);
+ if (res >= end)
+ return -1;
+ return res;
+ }
+
+ public static int ll_rfind_char(String haystack, char needle, int start, int end) {
+ int res = haystack.lastIndexOf(needle, end-1);
+ System.err.println("haystack="+haystack+" needle="+needle+" start="+start+
+ " end="+end+" res="+res);
+ if (res >= start)
+ return res;
+ return -1;
+ }
+
+ public static int ll_count_char(String haystack, char needle, int start, int end) {
+ haystack = haystack.substring(start, end);
+ int cnt = 0;
+ int idx = -1;
+ while ((idx = haystack.indexOf(needle, idx+1)) != -1) {
+ cnt++;
+ }
+ return cnt;
+ }
+
+ public static String ll_strip(String str, char ch, boolean left, boolean right) {
+ int start = 0;
+ int end = str.length();
+
+ if (left) {
+ while (start <= str.length() && str.charAt(start) == ch) start++;
+ }
+
+ if (right) {
+ while (end > start && str.charAt(end-1) == ch) end--;
+ }
+
+ return str.substring(start, end);
+ }
+
+ public static ArrayList ll_split_chr(String str, char c) {
+ ArrayList list = new ArrayList();
+ int lastidx = 0, idx = 0;
+ while ((idx = str.indexOf(c, lastidx)) != -1)
+ {
+ String sub = str.substring(lastidx, idx);
+ list.add(sub);
+ lastidx = idx+1;
+ }
+ list.add(str.substring(lastidx));
+ return list;
+ }
+
+ public static String ll_substring(String str, int start, int cnt) {
+ return str.substring(start,start+cnt);
+ }
+
// ----------------------------------------------------------------------
// StringBuffer
Added: pypy/dist/pypy/translator/jvm/test/test_string.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/jvm/test/test_string.py Fri Jan 12 13:25:03 2007
@@ -0,0 +1,23 @@
+import py
+from pypy.translator.jvm.test.runtest import JvmTest
+import pypy.translator.oosupport.test_template.string as oostring
+
+class TestJvmString(JvmTest, oostring.BaseTestString):
+
+ EMPTY_STRING_HASH = 0
+
+ def test_unichar_const(self):
+ py.test.skip("JVM doesn't support unicode for command line arguments")
+ test_unichar_eq = test_unichar_const
+ test_unichar_ord = test_unichar_const
+ test_unichar_hash = test_unichar_const
+
+ def test_upper(self):
+ py.test.skip("eval has trouble with evaluation of null literals")
+ test_lower = test_upper
+
+ def test_float(self):
+ py.test.skip("JVM does not yet support ooparse_float")
+
+ def test_getitem_exc(self):
+ py.test.skip("JVM has trouble with exceptions")
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Fri Jan 12 13:25:03 2007
@@ -152,6 +152,7 @@
jThrowable = JvmClassType('java.lang.Throwable')
jObject = JvmClassType('java.lang.Object')
jString = JvmClassType('java.lang.String')
+jCharSequence = JvmClassType('java.lang.CharSequence')
jArrayList = JvmClassType('java.util.ArrayList')
jHashMap = JvmClassType('java.util.HashMap')
jIterator = JvmClassType('java.util.Iterator')
Modified: pypy/dist/pypy/translator/oosupport/test_template/dict.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/test_template/dict.py (original)
+++ pypy/dist/pypy/translator/oosupport/test_template/dict.py Fri Jan 12 13:25:03 2007
@@ -21,20 +21,10 @@
return total
assert self.interpret(f, []) == 6
- def test_dict_of_dict(self):
- py.test.skip("CLI doesn't support recursive dicts")
-
- def test_recursive(self):
- py.test.skip("CLI doesn't support recursive dicts")
-
class BaseTestEmptyDict(BaseTestRemptydict):
- def test_iterate_over_empty_dict(self):
- py.test.skip("Iteration over empty dict is not supported, yet")
+ pass
class BaseTestConstantDict(BaseTestRconstantdict):
- def test_constant_r_dict(self):
- py.test.skip('r_dict is not supported, yet')
-
def test_tuple_as_key(self):
mydict = {('r',): 42}
def fn(ch):
Added: pypy/dist/pypy/translator/oosupport/test_template/string.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/oosupport/test_template/string.py Fri Jan 12 13:25:03 2007
@@ -0,0 +1,35 @@
+import py
+from pypy.rpython.test.test_rstr import BaseTestRstr
+
+class BaseTestString(BaseTestRstr):
+
+ def test_char_isxxx(self):
+ def fn(s):
+ return (s.isspace() |
+ s.isdigit() << 1 |
+ s.isalpha() << 2 |
+ s.isalnum() << 3 |
+ s.isupper() << 4 |
+ s.islower() << 5)
+ # need to start from 1, because we cannot pass '\x00' as a
+ # command line parameter
+ for i in range(1, 128):
+ ch = chr(i)
+ res = self.interpret(fn, [ch])
+ assert res == fn(ch)
+
+ def test_replace_TyperError(self):
+ pass # it doesn't make sense here
+
+ def test_hash_value(self):
+ # make that hash are computed by value and not by reference
+ def fn(x, y):
+ s1 = ''.join([x, 'e', 'l', 'l', 'o'])
+ s2 = ''.join([y, 'e', 'l', 'l', 'o'])
+ return (hash(s1) == hash(s2)) and (s1 is not s2)
+ assert self.interpret(fn, ['h', 'h']) == True
+
+ def test_int_formatting(self):
+ def fn(answer):
+ return 'the answer is %s' % answer
+ assert self.ll_to_string(self.interpret(fn, [42])) == 'the answer is 42'
From niko at codespeak.net Fri Jan 12 13:34:46 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Fri, 12 Jan 2007 13:34:46 +0100 (CET)
Subject: [pypy-svn] r36559 - pypy/dist/pypy/translator/jvm/test
Message-ID: <20070112123446.ABA1E1007C@code0.codespeak.net>
Author: niko
Date: Fri Jan 12 13:34:45 2007
New Revision: 36559
Modified:
pypy/dist/pypy/translator/jvm/test/test_dict.py
Log:
add annoying tests to the list of skipped tests
Modified: pypy/dist/pypy/translator/jvm/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/test_dict.py (original)
+++ pypy/dist/pypy/translator/jvm/test/test_dict.py Fri Jan 12 13:34:45 2007
@@ -6,8 +6,15 @@
def test_invalid_iterator(self):
py.test.skip("test_invalid_iterator() doesn't work yet")
+ def test_dict_of_dict(self):
+ py.test.skip("hard to serialize a recursive dictionary")
+
+ def test_recursive(self):
+ py.test.skip("hard to serialize a recursive dictionary")
+
class TestJvmEmptyDict(JvmTest, oodict.BaseTestEmptyDict):
- pass
+ def test_iterate_over_empty_dict(self):
+ py.test.skip("Iteration over empty dict is not supported, yet")
class TestJvmConstantDict(JvmTest, oodict.BaseTestConstantDict):
pass
From mwh at codespeak.net Fri Jan 12 13:40:01 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Fri, 12 Jan 2007 13:40:01 +0100 (CET)
Subject: [pypy-svn] r36561 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070112124001.32C831007C@code0.codespeak.net>
Author: mwh
Date: Fri Jan 12 13:39:59 2007
New Revision: 36561
Modified:
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
uh what the ppc isa doesn't have plain andi?
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Jan 12 13:39:59 2007
@@ -754,7 +754,7 @@
return self._compare('ge', gv_x, gv_y)
def op_int_and(self, gv_x, gv_y):
- return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.and_, _PPC.andi)
+ return self._arg_arg_op(gv_x, gv_y, _PPC.and_)
def op_int_or(self, gv_x, gv_y):
return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.or_, _PPC.ori)
From fijal at codespeak.net Fri Jan 12 13:40:23 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 13:40:23 +0100 (CET)
Subject: [pypy-svn] r36562 - pypy/dist/pypy/objspace/std
Message-ID: <20070112124023.9BCCA10080@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 13:40:21 2007
New Revision: 36562
Modified:
pypy/dist/pypy/objspace/std/proxyobject.py
pypy/dist/pypy/objspace/std/transparent.py
Log:
Add W_TransparentCode
Modified: pypy/dist/pypy/objspace/std/proxyobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/proxyobject.py (original)
+++ pypy/dist/pypy/objspace/std/proxyobject.py Fri Jan 12 13:40:21 2007
@@ -68,7 +68,14 @@
def setdict(self, space, w_dict):
if not self.setdictvalue(space, space.wrap('__dict__'), w_dict):
baseobjspace.W_Root.setdict(self, space, w_dict)
-
+
+## def __getattr__(self, attr):
+## # NOT_RPYTHON
+## try:
+## return self.getdictvalue(self.space, self.space.wrap(attr))
+## except OperationError, e:
+## raise AttributeError(attr)
+
W_Transparent.__name__ = name
return W_Transparent
@@ -78,7 +85,8 @@
from pypy.objspace.std.objecttype import object_typedef
W_TransparentObject.typedef = object_typedef
-from pypy.interpreter.typedef import Function, GeneratorIterator, PyTraceback, PyFrame
+from pypy.interpreter.typedef import Function, GeneratorIterator, PyTraceback, \
+ PyFrame, PyCode
class W_TransparentFunction(W_Transparent):
typedef = Function.typedef
@@ -86,6 +94,9 @@
class W_TransparentTraceback(W_Transparent):
typedef = PyTraceback.typedef
+class W_TransparentCode(W_Transparent):
+ typedef = PyCode.typedef
+
class W_TransparentFrame(W_Transparent):
typedef = PyFrame.typedef
Modified: pypy/dist/pypy/objspace/std/transparent.py
==============================================================================
--- pypy/dist/pypy/objspace/std/transparent.py (original)
+++ pypy/dist/pypy/objspace/std/transparent.py Fri Jan 12 13:40:21 2007
@@ -9,7 +9,8 @@
from pypy.objspace.std.typeobject import W_TypeObject
def proxy(space, w_type, w_controller):
- from pypy.interpreter.typedef import Function, PyTraceback, PyFrame, GeneratorIterator
+ from pypy.interpreter.typedef import Function, PyTraceback, PyFrame, \
+ PyCode, GeneratorIterator
if not space.is_true(space.callable(w_controller)):
raise OperationError(space.w_TypeError, space.wrap("controller should be function"))
@@ -27,6 +28,8 @@
return W_TransparentFrame(space, w_type, w_controller)
if space.is_true(space.issubtype(w_type, space.gettypeobject(GeneratorIterator.typedef))):
return W_TransparentGenerator(space, w_type, w_controller)
+ if space.is_true(space.issubtype(w_type, space.gettypeobject(PyCode.typedef))):
+ return W_TransparentCode(space, w_type, w_controller)
if w_type.instancetypedef is space.w_object.instancetypedef:
return W_Transparent(space, w_type, w_controller)
else:
From fijal at codespeak.net Fri Jan 12 13:42:30 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 13:42:30 +0100 (CET)
Subject: [pypy-svn] r36563 - pypy/dist/pypy/rlib
Message-ID: <20070112124230.10F761007C@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 13:42:28 2007
New Revision: 36563
Modified:
pypy/dist/pypy/rlib/nonconst.py
Log:
A bit of a cleanup
Modified: pypy/dist/pypy/rlib/nonconst.py
==============================================================================
--- pypy/dist/pypy/rlib/nonconst.py (original)
+++ pypy/dist/pypy/rlib/nonconst.py Fri Jan 12 13:42:28 2007
@@ -22,14 +22,13 @@
def compute_result_annotation(self, arg):
if hasattr(arg, 'const'):
- return getbookkeeper().annotation_from_example(arg.const)
+ return self.bookkeeper.annotation_from_example(arg.const)
else:
return arg
def specialize_call(self, hop):
- #v = Variable()
- #v.concretetype = hop.r_result.lowleveltype
hop.exception_cannot_occur()
retval = Constant(hop.r_result.convert_const(hop.args_v[0].value))
retval.concretetype = hop.r_result.lowleveltype
return retval
+
From fijal at codespeak.net Fri Jan 12 13:44:20 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 13:44:20 +0100 (CET)
Subject: [pypy-svn] r36564 - in pypy/branch/extfunc-cleanup: . pypy
pypy/objspace/std pypy/rlib pypy/rpython pypy/rpython/module
pypy/rpython/module/test pypy/rpython/test pypy/translator/c
pypy/translator/c/src pypy/translator/js
Message-ID: <20070112124420.92A011007D@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 13:44:13 2007
New Revision: 36564
Added:
pypy/branch/extfunc-cleanup/
- copied from r36426, pypy/dist/
pypy/branch/extfunc-cleanup/pypy/
- copied from r36552, pypy/dist/pypy/
pypy/branch/extfunc-cleanup/pypy/objspace/std/proxyobject.py
- copied unchanged from r36562, pypy/dist/pypy/objspace/std/proxyobject.py
pypy/branch/extfunc-cleanup/pypy/objspace/std/transparent.py
- copied unchanged from r36562, pypy/dist/pypy/objspace/std/transparent.py
pypy/branch/extfunc-cleanup/pypy/rlib/nonconst.py
- copied unchanged from r36563, pypy/dist/pypy/rlib/nonconst.py
pypy/branch/extfunc-cleanup/pypy/rpython/extfunc.py
- copied, changed from r36555, pypy/dist/pypy/rpython/extfunc.py
pypy/branch/extfunc-cleanup/pypy/rpython/test/test_extfunc.py
- copied unchanged from r36555, pypy/dist/pypy/rpython/test/test_extfunc.py
pypy/branch/extfunc-cleanup/pypy/translator/js/
- copied from r36562, pypy/dist/pypy/translator/js/
Modified:
pypy/branch/extfunc-cleanup/pypy/rpython/extfunctable.py
pypy/branch/extfunc-cleanup/pypy/rpython/module/ll_os.py
pypy/branch/extfunc-cleanup/pypy/rpython/module/support.py
pypy/branch/extfunc-cleanup/pypy/rpython/module/test/test_ll_os.py
pypy/branch/extfunc-cleanup/pypy/rpython/rtyper.py
pypy/branch/extfunc-cleanup/pypy/translator/c/extfunc.py
pypy/branch/extfunc-cleanup/pypy/translator/c/src/ll_os.h
Log:
Create a branch for replacing extfunc interface. It cannot be done on a trunk because we lack proper rcytpes.
Modified: pypy/branch/extfunc-cleanup/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/branch/extfunc-cleanup/pypy/rpython/extfunctable.py Fri Jan 12 13:44:13 2007
@@ -235,9 +235,9 @@
declare(os.spawnv, int, 'll_os/spawnv')
if hasattr(os, 'waitpid'):
declare(os.waitpid , waitpidannotation, 'll_os/waitpid')
-if hasattr(os, 'execv'):
- declare(os.execv, noneannotation, 'll_os/execv')
- declare(os.execve, noneannotation, 'll_os/execve')
+#if hasattr(os, 'execv'):
+# declare(os.execv, noneannotation, 'll_os/execv')
+# declare(os.execve, noneannotation, 'll_os/execve')
declare(os.path.exists, bool , 'll_os_path/exists')
declare(os.path.isdir, bool , 'll_os_path/isdir')
Modified: pypy/branch/extfunc-cleanup/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/branch/extfunc-cleanup/pypy/rpython/module/ll_os.py Fri Jan 12 13:44:13 2007
@@ -14,13 +14,39 @@
# and buffer preparation stuff is not useful.
import os, errno
-from pypy.rpython.module.support import ll_strcpy, _ll_strfill, ll_execve, \
- from_rdict
+from pypy.rpython.module.support import ll_strcpy, _ll_strfill
from pypy.rpython.module.support import to_opaque_object, from_opaque_object
from pypy.rlib import ros
from pypy.rlib.rarithmetic import r_longlong
from pypy.tool.staticmethods import ClassMethods
import stat
+from pypy.rpython.extfunc import ExtFuncEntry
+from pypy.annotation.model import SomeString, s_ImpossibleValue
+from pypy.annotation.listdef import s_list_of_strings
+import ctypes
+import pypy.rpython.rctypes.implementation
+from pypy.rpython.rctypes.tool.libc import libc
+from pypy.rpython.rctypes.aerrno import geterrno
+
+if hasattr(os, 'execv'):
+
+ os_execv = libc.execv
+ os_execv.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p)]
+ os_execv.restype = ctypes.c_int
+
+ class ExecvFuncEntry(ExtFuncEntry):
+ _about_ = os.execv
+ name = "ll_os_execv"
+ signature_args = [SomeString(), s_list_of_strings]
+ signature_result = s_ImpossibleValue
+
+ def lltypeimpl(path, args):
+ typ = ctypes.c_char_p * (len(args) + 1)
+ array = typ()
+ for num in range(len(args)):
+ array[num] = args[num]
+ os_execv(path, array)
+ raise OSError(geterrno())
class BaseOS:
__metaclass__ = ClassMethods
@@ -101,13 +127,13 @@
return os.system(cls.from_rstr(cmd))
ll_os_system.suggested_primitive = True
- def ll_os_execv(cls, cmd, args):
- os.execv(cmd, args)
- ll_os_execv.suggested_primitive = True
-
- def ll_os_execve(cls, cmd, args, env):
- env_list = from_rdict(env)
- ll_execve(cmd, args, env_list)
+ #def ll_os_execv(cls, cmd, args):
+ # os.execv(cmd, args)
+ #ll_os_execv.suggested_primitive = True
+
+ #def ll_os_execve(cls, cmd, args, env):
+ # env_list = from_rdict(env)
+ # ll_execve(cmd, args, env_list)
def ll_os_unlink(cls, path):
os.unlink(cls.from_rstr(path))
Modified: pypy/branch/extfunc-cleanup/pypy/rpython/module/support.py
==============================================================================
--- pypy/dist/pypy/rpython/module/support.py (original)
+++ pypy/branch/extfunc-cleanup/pypy/rpython/module/support.py Fri Jan 12 13:44:13 2007
@@ -15,16 +15,6 @@
from pypy.annotation.model import SomeString
import os
-# This whole mess is just to make annotator happy...
-list_repr = ListRepr(None, string_repr)
-list_repr.setup()
-LIST = list_repr.lowleveltype.TO
-tuple_repr = TupleRepr(None, [string_repr, string_repr])
-tuple_repr.setup()
-tuple_list_repr = ListRepr(None, tuple_repr)
-tuple_list_repr.setup()
-LIST_TUPLE = tuple_list_repr.lowleveltype.TO
-
# utility conversion functions
class LLSupport:
_mixin_ = True
@@ -46,32 +36,6 @@
return ''.join([rs.chars[i] for i in range(len(rs.chars))])
from_rstr = staticmethod(from_rstr)
-def from_rdict(rs):
- ritems = ll_kvi(rs, LIST_TUPLE, dum_items)
- res = ll_newlist(LIST, 0)
- index = 0
- while index < ritems.ll_length():
- ritem = ll_getitem_fast(ritems, index)
- ll_append(res, LLSupport.to_rstr("%s=%s" % (LLSupport.from_rstr(ritem.item0),
- LLSupport.from_rstr(ritem.item1))))
- index += 1
- return res
-
-def to_rdict(rs):
- d = {}
- index = 0
- while index < rs.ll_length():
- item = LLSupport.from_rstr(ll_getitem_fast(rs, index))
- key, value = item.split("=")
- d[key] = value
- index += 1
- return d
-
-def ll_execve(cmd, args, env_list):
- env = to_rdict(env_list)
- os.execve(cmd, args, env)
-ll_execve.suggested_primitive = True
-
class OOSupport:
_mixin_ = True
Modified: pypy/branch/extfunc-cleanup/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original)
+++ pypy/branch/extfunc-cleanup/pypy/rpython/module/test/test_ll_os.py Fri Jan 12 13:44:13 2007
@@ -1,7 +1,7 @@
import os
from pypy.tool.udir import udir
from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl
-
+import sys
def test_access():
filename = str(udir.join('test_access.txt'))
@@ -112,3 +112,22 @@
compared_with = os.listdir(dirname)
compared_with.sort()
assert result == compared_with
+
+if hasattr(os, 'execv'):
+ from pypy.rpython.extregistry import lookup
+ os_execv = lookup(os.execv).lltypeimpl.im_func
+
+ def test_execv():
+ filename = str(udir.join('test_execv_ctypes.txt'))
+
+ progname = str(sys.executable)
+ l = ['', '']
+ l[0] = progname
+ l[1] = "-c"
+ l.append('open("%s","w").write("1")' % filename)
+ pid = os.fork()
+ if pid == 0:
+ os_execv(progname, l)
+ else:
+ os.waitpid(pid, 0)
+ assert open(filename).read() == "1"
Modified: pypy/branch/extfunc-cleanup/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/branch/extfunc-cleanup/pypy/rpython/rtyper.py Fri Jan 12 13:44:13 2007
@@ -919,6 +919,7 @@
from pypy.rpython import rstr, rdict, rlist
from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
from pypy.rpython import rexternalobj
+from pypy.rpython import rgeneric
from pypy.rpython import rptr
from pypy.rpython import raddress # memory addresses
from pypy.rpython.ootypesystem import rootype
Modified: pypy/branch/extfunc-cleanup/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/branch/extfunc-cleanup/pypy/translator/c/extfunc.py Fri Jan 12 13:44:13 2007
@@ -5,9 +5,8 @@
from pypy.rpython.lltypesystem.rstr import STR, mallocstr
from pypy.rpython.lltypesystem import rstr
from pypy.rpython.lltypesystem import rlist
-from pypy.rpython.module import ll_time, ll_math
+from pypy.rpython.module import ll_time, ll_math, ll_os
from pypy.rpython.module import ll_stackless, ll_stack
-from pypy.rpython.module.support import ll_execve
from pypy.rpython.lltypesystem.module.ll_os import STAT_RESULT, PIPE_RESULT
from pypy.rpython.lltypesystem.module.ll_os import WAITPID_RESULT
from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl
@@ -64,8 +63,6 @@
impl.ll_os_spawnv.im_func: 'LL_os_spawnv',
impl.ll_os_waitpid.im_func: 'LL_os_waitpid',
impl.ll_os__exit.im_func: 'LL_os__exit',
- impl.ll_os_execv.im_func: 'LL_os_execv',
- ll_execve: 'LL_os_execve',
ll_time.ll_time_clock: 'LL_time_clock',
ll_time.ll_time_sleep: 'LL_time_sleep',
ll_time.ll_time_time: 'LL_time_time',
Modified: pypy/branch/extfunc-cleanup/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h (original)
+++ pypy/branch/extfunc-cleanup/pypy/translator/c/src/ll_os.h Fri Jan 12 13:44:13 2007
@@ -81,11 +81,7 @@
void LL_os_symlink(RPyString * path1, RPyString * path2);
long LL_readlink_into(RPyString *path, RPyString *buffer);
long LL_os_fork(void);
-#ifdef HAVE_RPY_LIST_OF_STRING /* argh */
-#ifdef HAVE_EXECV
-void LL_os_execv(RPyString *cmd, RPyListOfString *args);
-void LL_os_execve(RPyString *cmd, RPyListOfString *args, RPyListOfString *env);
-#endif
+#if defined(HAVE_SPAWNV) && defined(HAVE_RPY_LIST_OF_STRING) /* argh */
long LL_os_spawnv(int mode, RPyString *path, RPyListOfString *args);
#endif
RPyWAITPID_RESULT* LL_os_waitpid(long pid, long options);
@@ -404,39 +400,6 @@
}
#endif
-#if defined(HAVE_EXECV) && defined(HAVE_RPY_LIST_OF_STRING)
-char** get_slist(RPyListOfString *args)
-{
- int i, nargs = _RPyListOfString_Length(args);
- char **slist = malloc((nargs+1) * sizeof(char*));
- if (slist) {
- for (i=0; i
Author: fijal
Date: Fri Jan 12 13:45:16 2007
New Revision: 36565
Modified:
pypy/dist/pypy/rpython/extfunc.py
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/rpython/module/support.py
pypy/dist/pypy/rpython/module/test/test_ll_os.py
pypy/dist/pypy/rpython/rtyper.py
pypy/dist/pypy/translator/c/extfunc.py
pypy/dist/pypy/translator/c/src/ll_os.h
Log:
Add attempt to implement os.execv to a branch. Looks like it should be working, but no proper support from rctypes.
Modified: pypy/dist/pypy/rpython/extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunc.py (original)
+++ pypy/dist/pypy/rpython/extfunc.py Fri Jan 12 13:45:16 2007
@@ -2,12 +2,14 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.lltypesystem.lltype import typeOf
from pypy.objspace.flow.model import Constant
+from pypy.annotation.model import unionof
class ExtFuncEntry(ExtRegistryEntry):
def compute_result_annotation(self, *args_s):
assert len(args_s) == len(self.signature_args),\
"Argument number mismatch"
for arg, expected in zip(args_s, self.signature_args):
+ arg = unionof(arg, expected)
assert expected.contains(arg)
for type_system in ['lltype', 'ootype']:
@@ -17,6 +19,7 @@
pbc = self.bookkeeper.immutablevalue(impl.im_func)
s_result = self.bookkeeper.emulate_pbc_call(key, pbc,
self.signature_args)
+ s_result = unionof(s_result, self.signature_result)
assert self.signature_result.contains(s_result)
return self.signature_result
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Fri Jan 12 13:45:16 2007
@@ -235,9 +235,9 @@
declare(os.spawnv, int, 'll_os/spawnv')
if hasattr(os, 'waitpid'):
declare(os.waitpid , waitpidannotation, 'll_os/waitpid')
-if hasattr(os, 'execv'):
- declare(os.execv, noneannotation, 'll_os/execv')
- declare(os.execve, noneannotation, 'll_os/execve')
+#if hasattr(os, 'execv'):
+# declare(os.execv, noneannotation, 'll_os/execv')
+# declare(os.execve, noneannotation, 'll_os/execve')
declare(os.path.exists, bool , 'll_os_path/exists')
declare(os.path.isdir, bool , 'll_os_path/isdir')
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jan 12 13:45:16 2007
@@ -14,13 +14,39 @@
# and buffer preparation stuff is not useful.
import os, errno
-from pypy.rpython.module.support import ll_strcpy, _ll_strfill, ll_execve, \
- from_rdict
+from pypy.rpython.module.support import ll_strcpy, _ll_strfill
from pypy.rpython.module.support import to_opaque_object, from_opaque_object
from pypy.rlib import ros
from pypy.rlib.rarithmetic import r_longlong
from pypy.tool.staticmethods import ClassMethods
import stat
+from pypy.rpython.extfunc import ExtFuncEntry
+from pypy.annotation.model import SomeString, s_ImpossibleValue
+from pypy.annotation.listdef import s_list_of_strings
+import ctypes
+import pypy.rpython.rctypes.implementation
+from pypy.rpython.rctypes.tool.libc import libc
+from pypy.rpython.rctypes.aerrno import geterrno
+
+if hasattr(os, 'execv'):
+
+ os_execv = libc.execv
+ os_execv.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p)]
+ os_execv.restype = ctypes.c_int
+
+ class ExecvFuncEntry(ExtFuncEntry):
+ _about_ = os.execv
+ name = "ll_os_execv"
+ signature_args = [SomeString(), s_list_of_strings]
+ signature_result = s_ImpossibleValue
+
+ def lltypeimpl(path, args):
+ typ = ctypes.c_char_p * (len(args) + 1)
+ array = typ()
+ for num in range(len(args)):
+ array[num] = args[num]
+ os_execv(path, array)
+ raise OSError(geterrno())
class BaseOS:
__metaclass__ = ClassMethods
@@ -101,13 +127,13 @@
return os.system(cls.from_rstr(cmd))
ll_os_system.suggested_primitive = True
- def ll_os_execv(cls, cmd, args):
- os.execv(cmd, args)
- ll_os_execv.suggested_primitive = True
-
- def ll_os_execve(cls, cmd, args, env):
- env_list = from_rdict(env)
- ll_execve(cmd, args, env_list)
+ #def ll_os_execv(cls, cmd, args):
+ # os.execv(cmd, args)
+ #ll_os_execv.suggested_primitive = True
+
+ #def ll_os_execve(cls, cmd, args, env):
+ # env_list = from_rdict(env)
+ # ll_execve(cmd, args, env_list)
def ll_os_unlink(cls, path):
os.unlink(cls.from_rstr(path))
Modified: pypy/dist/pypy/rpython/module/support.py
==============================================================================
--- pypy/dist/pypy/rpython/module/support.py (original)
+++ pypy/dist/pypy/rpython/module/support.py Fri Jan 12 13:45:16 2007
@@ -15,16 +15,6 @@
from pypy.annotation.model import SomeString
import os
-# This whole mess is just to make annotator happy...
-list_repr = ListRepr(None, string_repr)
-list_repr.setup()
-LIST = list_repr.lowleveltype.TO
-tuple_repr = TupleRepr(None, [string_repr, string_repr])
-tuple_repr.setup()
-tuple_list_repr = ListRepr(None, tuple_repr)
-tuple_list_repr.setup()
-LIST_TUPLE = tuple_list_repr.lowleveltype.TO
-
# utility conversion functions
class LLSupport:
_mixin_ = True
@@ -46,32 +36,6 @@
return ''.join([rs.chars[i] for i in range(len(rs.chars))])
from_rstr = staticmethod(from_rstr)
-def from_rdict(rs):
- ritems = ll_kvi(rs, LIST_TUPLE, dum_items)
- res = ll_newlist(LIST, 0)
- index = 0
- while index < ritems.ll_length():
- ritem = ll_getitem_fast(ritems, index)
- ll_append(res, LLSupport.to_rstr("%s=%s" % (LLSupport.from_rstr(ritem.item0),
- LLSupport.from_rstr(ritem.item1))))
- index += 1
- return res
-
-def to_rdict(rs):
- d = {}
- index = 0
- while index < rs.ll_length():
- item = LLSupport.from_rstr(ll_getitem_fast(rs, index))
- key, value = item.split("=")
- d[key] = value
- index += 1
- return d
-
-def ll_execve(cmd, args, env_list):
- env = to_rdict(env_list)
- os.execve(cmd, args, env)
-ll_execve.suggested_primitive = True
-
class OOSupport:
_mixin_ = True
Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Fri Jan 12 13:45:16 2007
@@ -1,7 +1,7 @@
import os
from pypy.tool.udir import udir
from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl
-
+import sys
def test_access():
filename = str(udir.join('test_access.txt'))
@@ -112,3 +112,22 @@
compared_with = os.listdir(dirname)
compared_with.sort()
assert result == compared_with
+
+if hasattr(os, 'execv'):
+ from pypy.rpython.extregistry import lookup
+ os_execv = lookup(os.execv).lltypeimpl.im_func
+
+ def test_execv():
+ filename = str(udir.join('test_execv_ctypes.txt'))
+
+ progname = str(sys.executable)
+ l = ['', '']
+ l[0] = progname
+ l[1] = "-c"
+ l.append('open("%s","w").write("1")' % filename)
+ pid = os.fork()
+ if pid == 0:
+ os_execv(progname, l)
+ else:
+ os.waitpid(pid, 0)
+ assert open(filename).read() == "1"
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Fri Jan 12 13:45:16 2007
@@ -919,6 +919,7 @@
from pypy.rpython import rstr, rdict, rlist
from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
from pypy.rpython import rexternalobj
+from pypy.rpython import rgeneric
from pypy.rpython import rptr
from pypy.rpython import raddress # memory addresses
from pypy.rpython.ootypesystem import rootype
Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/dist/pypy/translator/c/extfunc.py Fri Jan 12 13:45:16 2007
@@ -5,9 +5,8 @@
from pypy.rpython.lltypesystem.rstr import STR, mallocstr
from pypy.rpython.lltypesystem import rstr
from pypy.rpython.lltypesystem import rlist
-from pypy.rpython.module import ll_time, ll_math
+from pypy.rpython.module import ll_time, ll_math, ll_os
from pypy.rpython.module import ll_stackless, ll_stack
-from pypy.rpython.module.support import ll_execve
from pypy.rpython.lltypesystem.module.ll_os import STAT_RESULT, PIPE_RESULT
from pypy.rpython.lltypesystem.module.ll_os import WAITPID_RESULT
from pypy.rpython.lltypesystem.module.ll_os import Implementation as impl
@@ -64,8 +63,6 @@
impl.ll_os_spawnv.im_func: 'LL_os_spawnv',
impl.ll_os_waitpid.im_func: 'LL_os_waitpid',
impl.ll_os__exit.im_func: 'LL_os__exit',
- impl.ll_os_execv.im_func: 'LL_os_execv',
- ll_execve: 'LL_os_execve',
ll_time.ll_time_clock: 'LL_time_clock',
ll_time.ll_time_sleep: 'LL_time_sleep',
ll_time.ll_time_time: 'LL_time_time',
Modified: pypy/dist/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h (original)
+++ pypy/dist/pypy/translator/c/src/ll_os.h Fri Jan 12 13:45:16 2007
@@ -81,11 +81,7 @@
void LL_os_symlink(RPyString * path1, RPyString * path2);
long LL_readlink_into(RPyString *path, RPyString *buffer);
long LL_os_fork(void);
-#ifdef HAVE_RPY_LIST_OF_STRING /* argh */
-#ifdef HAVE_EXECV
-void LL_os_execv(RPyString *cmd, RPyListOfString *args);
-void LL_os_execve(RPyString *cmd, RPyListOfString *args, RPyListOfString *env);
-#endif
+#if defined(HAVE_SPAWNV) && defined(HAVE_RPY_LIST_OF_STRING) /* argh */
long LL_os_spawnv(int mode, RPyString *path, RPyListOfString *args);
#endif
RPyWAITPID_RESULT* LL_os_waitpid(long pid, long options);
@@ -404,39 +400,6 @@
}
#endif
-#if defined(HAVE_EXECV) && defined(HAVE_RPY_LIST_OF_STRING)
-char** get_slist(RPyListOfString *args)
-{
- int i, nargs = _RPyListOfString_Length(args);
- char **slist = malloc((nargs+1) * sizeof(char*));
- if (slist) {
- for (i=0; i
Author: antocuni
Date: Fri Jan 12 13:45:53 2007
New Revision: 36566
Modified:
pypy/dist/pypy/config/translationoption.py
pypy/dist/pypy/translator/driver.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/node.py
pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
pypy/dist/pypy/translator/jvm/typesystem.py
Log:
(antocuni, niko)
Add jvm backend to translate.py.
Fix bugs in the standalone entrypoint of jvm backend.
Modified: pypy/dist/pypy/config/translationoption.py
==============================================================================
--- pypy/dist/pypy/config/translationoption.py (original)
+++ pypy/dist/pypy/config/translationoption.py Fri Jan 12 13:45:53 2007
@@ -11,13 +11,14 @@
ChoiceOption("type_system", "Type system to use when RTyping",
["lltype", "ootype"], cmdline=None),
ChoiceOption("backend", "Backend to use for code generation",
- ["c", "llvm", "cli", "js", "squeak", "cl"],
+ ["c", "llvm", "cli", "jvm", "js", "squeak", "cl"],
requires={
"c": [("translation.type_system", "lltype")],
"llvm": [("translation.type_system", "lltype"),
("translation.gc", "boehm"),
("translation.backendopt.raisingop2direct_call", True)],
"cli": [("translation.type_system", "ootype")],
+ "jvm": [("translation.type_system", "ootype")],
"js": [("translation.type_system", "ootype")],
"squeak": [("translation.type_system", "ootype")],
"cl": [("translation.type_system", "ootype")],
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Fri Jan 12 13:45:53 2007
@@ -620,7 +620,29 @@
pass
task_run_cli = taskdef(task_run_cli, ['compile_cli'],
'XXX')
+
+ def task_source_jvm(self):
+ from pypy.translator.jvm.genjvm import GenJvm
+ from pypy.translator.jvm.node import EntryPoint
+
+ entry_point_graph = self.translator.graphs[0]
+ entry_point = EntryPoint(entry_point_graph, False, False)
+ self.gen = GenJvm(udir, self.translator, entry_point)
+ self.jvmsource = self.gen.generate_source()
+ self.log.info("Wrote JVM code")
+ task_source_jvm = taskdef(task_source_jvm, ["?" + OOBACKENDOPT, OOTYPE],
+ 'Generating JVM source')
+
+ def task_compile_jvm(self):
+ self.jvmsource.compile()
+ self.log.info("Compiled JVM source")
+ task_compile_jvm = taskdef(task_compile_jvm, ['source_jvm'],
+ 'Compiling JVM source')
+ def task_run_jvm(self):
+ pass
+ task_run_jvm = taskdef(task_run_jvm, ['compile_jvm'],
+ 'XXX')
def proceed(self, goals):
if not goals:
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Fri Jan 12 13:45:53 2007
@@ -9,7 +9,8 @@
JvmType, jString, jInt, jLong, jDouble, jBool, jString, \
jPyPy, jVoid, jMath, desc_for_method, jPrintStream, jClass, jChar, \
jObject, jByteArray, jPyPyExcWrap, jIntegerClass, jLongClass, \
- jDoubleClass, jCharClass, jStringBuilder, JvmScalarType
+ jDoubleClass, jCharClass, jStringBuilder, JvmScalarType, jArrayList, \
+ jObjectArray
# ___________________________________________________________________________
# Miscellaneous helper functions
@@ -370,6 +371,7 @@
PYPYDUMPEXCWRAPPER = Method.s(jPyPy, 'dump_exc_wrapper', (jObject,), jVoid)
PYPYRUNTIMENEW = Method.s(jPyPy, 'RuntimeNew', (jClass,), jObject)
PYPYSTRING2BYTES = Method.s(jPyPy, 'string2bytes', (jString,), jByteArray)
+PYPYARRAYTOLIST = Method.s(jPyPy, 'array_to_list', (jObjectArray,), jArrayList)
OBJECTGETCLASS = Method.v(jObject, 'getClass', (), jClass)
CLASSGETNAME = Method.v(jClass, 'getName', (), jString)
EXCWRAPWRAP = Method.s(jPyPyExcWrap, 'wrap', (jObject,), jPyPyExcWrap)
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Fri Jan 12 13:45:53 2007
@@ -111,8 +111,8 @@
# python method expects
arg0 = self.graph.getargs()[0]
assert isinstance(arg0.concretetype, ootype.List), str(arg0.concretetype)
- assert arg0._ITEMTYPE is ootype.String
- gen.load_jvm_var(0)
+ assert arg0.concretetype._ITEMTYPE is ootype.String
+ gen.load_jvm_var(jStringArray, 0)
gen.emit(jvmgen.PYPYARRAYTOLIST)
# Generate a call to this method
Modified: pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java Fri Jan 12 13:45:53 2007
@@ -3,6 +3,7 @@
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Arrays;
/**
* Class with a number of utility routines.
@@ -115,14 +116,6 @@
return ~value;
}
- public static List> array_to_list(Object[] array) {
- List l = new ArrayList();
- for (Object o : array) {
- l.add(o);
- }
- return l;
- }
-
public static int str_to_int(String s) {
try {
return Integer.parseInt(s);
@@ -430,6 +423,11 @@
sb.append(s);
}
+ public static ArrayList array_to_list(Object[] array)
+ {
+ return new ArrayList(java.util.Arrays.asList(array));
+ }
+
// ----------------------------------------------------------------------
// OOString support
@@ -573,4 +571,4 @@
System.out.println("Total Failures: "+__failures);
}
-}
\ No newline at end of file
+}
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Fri Jan 12 13:45:53 2007
@@ -154,6 +154,7 @@
jString = JvmClassType('java.lang.String')
jCharSequence = JvmClassType('java.lang.CharSequence')
jArrayList = JvmClassType('java.util.ArrayList')
+jArrays = JvmClassType('java.util.Arrays')
jHashMap = JvmClassType('java.util.HashMap')
jIterator = JvmClassType('java.util.Iterator')
jClass = JvmClassType('java.lang.Class')
From fijal at codespeak.net Fri Jan 12 13:53:30 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 13:53:30 +0100 (CET)
Subject: [pypy-svn] r36567 - pypy/dist/pypy/rpython
Message-ID: <20070112125330.1D33610070@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 13:53:28 2007
New Revision: 36567
Modified:
pypy/dist/pypy/rpython/rtyper.py
Log:
Ooops. Didn't mean to check that in.
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Fri Jan 12 13:53:28 2007
@@ -919,7 +919,6 @@
from pypy.rpython import rstr, rdict, rlist
from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
from pypy.rpython import rexternalobj
-from pypy.rpython import rgeneric
from pypy.rpython import rptr
from pypy.rpython import raddress # memory addresses
from pypy.rpython.ootypesystem import rootype
From arigo at codespeak.net Fri Jan 12 14:01:33 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Fri, 12 Jan 2007 14:01:33 +0100 (CET)
Subject: [pypy-svn] r36568 - in pypy/dist/pypy: module/posix rpython/module
translator/c/test
Message-ID: <20070112130133.8958610084@code0.codespeak.net>
Author: arigo
Date: Fri Jan 12 14:01:30 2007
New Revision: 36568
Modified:
pypy/dist/pypy/module/posix/__init__.py
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/translator/c/test/test_extfunc.py
Log:
Whack at the ctypes implementation of execv() until rctypes is happy with it.
Skip execve.
Modified: pypy/dist/pypy/module/posix/__init__.py
==============================================================================
--- pypy/dist/pypy/module/posix/__init__.py (original)
+++ pypy/dist/pypy/module/posix/__init__.py Fri Jan 12 14:01:30 2007
@@ -74,7 +74,7 @@
interpleveldefs['waitpid'] = 'interp_posix.waitpid'
if hasattr(os, 'execv'):
interpleveldefs['execv'] = 'interp_posix.execv'
- if hasattr(os, 'execve'):
+ if hasattr(os, 'execve') and 0: # XXX XXX in-progress
interpleveldefs['execve'] = 'interp_posix.execve'
#if hasattr(ctypes_posix, 'uname'):
# interpleveldefs['uname'] = 'interp_posix.uname'
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jan 12 14:01:30 2007
@@ -41,12 +41,19 @@
signature_result = s_ImpossibleValue
def lltypeimpl(path, args):
- typ = ctypes.c_char_p * (len(args) + 1)
- array = typ()
+ # XXX incredible code to work around rctypes limitations
+ length = len(args) + 1
+ num_bytes = ctypes.sizeof(ctypes.c_char_p) * length
+ buffer = ctypes.create_string_buffer(num_bytes)
+ array = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_char_p))
+ buffer_addr = ctypes.cast(buffer, ctypes.c_void_p).value
for num in range(len(args)):
- array[num] = args[num]
+ adr1 = buffer_addr + ctypes.sizeof(ctypes.c_char_p) * num
+ ptr = ctypes.c_void_p(adr1)
+ arrayitem = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_char_p))
+ arrayitem[0] = args[num]
os_execv(path, array)
- raise OSError(geterrno())
+ raise OSError(geterrno(), "execv failed")
class BaseOS:
__metaclass__ = ClassMethods
Modified: pypy/dist/pypy/translator/c/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_extfunc.py (original)
+++ pypy/dist/pypy/translator/c/test/test_extfunc.py Fri Jan 12 14:01:30 2007
@@ -731,6 +731,7 @@
py.test.raises(OSError, "func()")
def test_execve():
+ import py; py.test.skip("in-progress")
filename = str(udir.join('test_execve.txt'))
def does_stuff():
progname = str(sys.executable)
From cfbolz at codespeak.net Fri Jan 12 14:05:53 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 14:05:53 +0100 (CET)
Subject: [pypy-svn] r36569 - in pypy/dist/pypy: rpython rpython/module
translator/c translator/c/src
Message-ID: <20070112130553.90A7310084@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 14:05:52 2007
New Revision: 36569
Modified:
pypy/dist/pypy/rpython/extfunctable.py
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/translator/c/extfunc.py
pypy/dist/pypy/translator/c/src/ll_os.h
Log:
rewrite dup and dup2 in the new style
Modified: pypy/dist/pypy/rpython/extfunctable.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunctable.py (original)
+++ pypy/dist/pypy/rpython/extfunctable.py Fri Jan 12 14:05:52 2007
@@ -195,8 +195,6 @@
declare(os.read , str , 'll_os/read')
declare(os.write , posannotation , 'll_os/write')
declare(os.close , noneannotation, 'll_os/close')
-declare(os.dup , int , 'll_os/dup')
-declare(os.dup2 , noneannotation, 'll_os/dup2')
declare(os.access , int , 'll_os/access')
declare(os.lseek , r_longlong , 'll_os/lseek')
declare(os.isatty , bool , 'll_os/isatty')
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jan 12 14:05:52 2007
@@ -21,7 +21,8 @@
from pypy.tool.staticmethods import ClassMethods
import stat
from pypy.rpython.extfunc import ExtFuncEntry
-from pypy.annotation.model import SomeString, s_ImpossibleValue
+from pypy.annotation.model import SomeString, SomeInteger, s_ImpossibleValue, \
+ s_None
from pypy.annotation.listdef import s_list_of_strings
import ctypes
import pypy.rpython.rctypes.implementation
@@ -55,6 +56,37 @@
os_execv(path, array)
raise OSError(geterrno(), "execv failed")
+os_dup = libc.dup
+os_dup.argtypes = [ctypes.c_int]
+os_dup.restype = ctypes.c_int
+
+class DupFuncEntry(ExtFuncEntry):
+ _about_ = os.dup
+ name = "ll_os_dup"
+ signature_args = [SomeInteger()]
+ signature_result = SomeInteger()
+
+ def lltypeimpl(fd):
+ newfd = os_dup(fd)
+ if newfd == -1:
+ raise OSError(geterrno(), "dup failed")
+ return newfd
+
+os_dup2 = libc.dup2
+os_dup2.argtypes = [ctypes.c_int, ctypes.c_int]
+os_dup2.restype = ctypes.c_int
+
+class Dup2FuncEntry(ExtFuncEntry):
+ _about_ = os.dup2
+ name = "ll_os_dup2"
+ signature_args = [SomeInteger(), SomeInteger()]
+ signature_result = s_None
+
+ def lltypeimpl(fd, newfd):
+ error = os_dup2(fd, newfd)
+ if error == -1:
+ raise OSError(geterrno(), "dup2 failed")
+
class BaseOS:
__metaclass__ = ClassMethods
Modified: pypy/dist/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/dist/pypy/translator/c/extfunc.py (original)
+++ pypy/dist/pypy/translator/c/extfunc.py Fri Jan 12 14:05:52 2007
@@ -28,8 +28,6 @@
impl.ll_read_into: 'LL_read_into', # it's a staticmethod
impl.ll_os_write.im_func: 'LL_os_write',
impl.ll_os_close.im_func: 'LL_os_close',
- impl.ll_os_dup.im_func: 'LL_os_dup',
- impl.ll_os_dup2.im_func: 'LL_os_dup2',
impl.ll_os_access.im_func: 'LL_os_access',
impl.ll_os_stat.im_func: 'LL_os_stat',
impl.ll_os_fstat.im_func: 'LL_os_fstat',
Modified: pypy/dist/pypy/translator/c/src/ll_os.h
==============================================================================
--- pypy/dist/pypy/translator/c/src/ll_os.h (original)
+++ pypy/dist/pypy/translator/c/src/ll_os.h Fri Jan 12 14:05:52 2007
@@ -55,8 +55,6 @@
long LL_read_into(int fd, RPyString *buffer);
long LL_os_write(int fd, RPyString *buffer);
void LL_os_close(int fd);
-int LL_os_dup(int fd);
-void LL_os_dup2(int old_fd, int new_fd);
int LL_os_access(RPyString *filename, int mode);
RPySTAT_RESULT* _stat_construct_result_helper(STRUCT_STAT st);
RPySTAT_RESULT* LL_os_stat(RPyString * fname);
@@ -136,21 +134,6 @@
RPYTHON_RAISE_OSERROR(errno);
}
-int LL_os_dup(int fd)
-{
- fd = dup(fd);
- if (fd < 0)
- RPYTHON_RAISE_OSERROR(errno);
- return fd;
-}
-
-void LL_os_dup2(int old_fd, int new_fd)
-{
- new_fd = dup2(old_fd, new_fd);
- if (new_fd < 0)
- RPYTHON_RAISE_OSERROR(errno);
-}
-
int LL_os_access(RPyString *filename, int mode) {
int n = access(RPyString_AsString(filename), mode);
return (n == 0);
From pedronis at codespeak.net Fri Jan 12 14:14:50 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 12 Jan 2007 14:14:50 +0100 (CET)
Subject: [pypy-svn] r36571 - in pypy/dist/pypy: jit/codegen/llgraph
jit/codegen/llgraph/test rpython rpython/lltypesystem
Message-ID: <20070112131450.DC55110060@code0.codespeak.net>
Author: pedronis
Date: Fri Jan 12 14:14:46 2007
New Revision: 36571
Modified:
pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
pypy/dist/pypy/rpython/llinterp.py
pypy/dist/pypy/rpython/lltypesystem/lloperation.py
Log:
(arre, pedronis)
add support for reading vars out of runtime frames for llinterp and codegen/llgraph
Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Fri Jan 12 14:14:46 2007
@@ -543,3 +543,35 @@
#setannotation(placeholder, s_ConstOrVar, specialize_as_constant=True)
setannotation(show_incremental_progress, None)
+
+# read frame var support
+
+def read_frame_var(T, base, info, index):
+ vars = info._obj.vars
+ v = vars[index]
+ if isinstance(v, flowmodel.Constant):
+ val = v.value
+ else:
+ llframe = base.ptr
+ val = llframe.bindings[v]
+ assert lltype.typeOf(val) == T
+ return val
+
+
+class ReadFrameVarEntry(ExtRegistryEntry):
+ "Annotation and specialization for calls to 'func'."
+ _about_ = read_frame_var
+
+ def compute_result_annotation(self, *args_s):
+ T = args_s[0].const
+ return annmodel.lltype_to_annotation(T)
+
+ # specialize as direct_call
+ def specialize_call(self, hop):
+ FUNCTYPE = lltype.FuncType([r.lowleveltype for r in hop.args_r],
+ hop.r_result.lowleveltype)
+ args_v = hop.inputargs(*hop.args_r)
+ funcptr = lltype.functionptr(FUNCTYPE, 'read_frame_var',
+ _callable=read_frame_var)
+ cfunc = hop.inputconst(lltype.Ptr(FUNCTYPE), funcptr)
+ return hop.genop('direct_call', [cfunc] + args_v, hop.r_result)
Modified: pypy/dist/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/rgenop.py Fri Jan 12 14:14:46 2007
@@ -1,5 +1,5 @@
from pypy.rlib.objectmodel import specialize
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.llgraph import llimpl
@@ -39,6 +39,8 @@
gv_Signed = gv_TYPE(lltype.Signed)
gv_dummy_placeholder = LLConst(llimpl.dummy_placeholder)
+gv_Address = gv_TYPE(llmemory.Address)
+gv_GCREF = gv_TYPE(llmemory.GCREF)
class LLLabel(GenLabel):
def __init__(self, b, g):
@@ -220,6 +222,16 @@
llimpl.show_incremental_progress(self.gv_f)
+ # read_frame_var support
+
+ def get_frame_base(self):
+ return LLVar(llimpl.genop(self.b, 'get_frame_base', [],
+ gv_Address.v))
+
+ def get_frame_info(self, vars):
+ return LLVar(llimpl.genop(self.b, 'get_frame_info', vars,
+ gv_GCREF.v))
+
class RGenOp(AbstractRGenOp):
gv_Void = gv_Void
@@ -302,5 +314,10 @@
def _freeze_(self):
return True # no real point in using a full class in llgraph
+ @staticmethod
+ @specialize.arg(0)
+ def read_frame_var(T, base, info, index):
+ return llimpl.read_frame_var(T, base, info, index)
+
rgenop = RGenOp() # no real point in using a full class in llgraph
Modified: pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/test/test_rgenop.py Fri Jan 12 14:14:46 2007
@@ -1,9 +1,9 @@
import py
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.llgraph.rgenop import RGenOp
from pypy.jit.codegen.llgraph.llimpl import testgengraph
from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests
-from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test.test_llinterp import gengraph, interpret
class TestLLGraphRGenop(AbstractRGenOpTests):
@@ -23,3 +23,35 @@
# for the individual tests see
# ====> ../../test/rgenop_tests.py
+
+
+def test_read_frame_var():
+ from pypy.annotation import model as annmodel
+
+ def reader(base, info):
+ return RGenOp.read_frame_var(lltype.Signed, base, info, 0)
+
+ t, rtyper, reader_graph = gengraph(reader,
+ [annmodel.SomeAddress(),
+ annmodel.SomePtr(llmemory.GCREF)])
+ reader_ptr = rtyper.getcallable(reader_graph)
+
+ F1 = lltype.FuncType([lltype.Signed], lltype.Signed)
+ rgenop = RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(F1)
+ gv_reader = RGenOp.constPrebuiltGlobal(reader_ptr)
+ readertoken = rgenop.sigToken(lltype.typeOf(reader_ptr).TO)
+
+ builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "f")
+
+ gv_y = builder.genop2("int_mul", gv_x, rgenop.genconst(2))
+ gv_base = builder.get_frame_base()
+ gv_info = builder.get_frame_info([gv_y])
+ gv_z = builder.genop_call(readertoken, gv_reader, [gv_base, gv_info])
+ builder.finish_and_return(sigtoken, gv_z)
+ builder.end()
+
+ ptr = gv_f.revealconst(lltype.Ptr(F1))
+ res = testgengraph(ptr._obj.graph, [21])
+ assert res == 42
Modified: pypy/dist/pypy/rpython/llinterp.py
==============================================================================
--- pypy/dist/pypy/rpython/llinterp.py (original)
+++ pypy/dist/pypy/rpython/llinterp.py Fri Jan 12 14:14:46 2007
@@ -356,24 +356,27 @@
assert isinstance(operation.args[0], Constant)
elif operation.opname == 'indirect_call':
assert isinstance(operation.args[0], Variable)
- vals = [self.getval(x) for x in operation.args]
- if getattr(ophandler, 'need_result_type', False):
- vals.insert(0, operation.result.concretetype)
- try:
- retval = ophandler(*vals)
- except LLException, e:
- # safety check check that the operation is allowed to raise that
- # exception
- if operation.opname in lloperation.LL_OPERATIONS:
- canraise = lloperation.LL_OPERATIONS[operation.opname].canraise
- if Exception not in canraise:
- exc = self.llinterpreter.find_exception(e)
- for canraiseexc in canraise:
- if issubclass(exc, canraiseexc):
- break
- else:
- raise TypeError("the operation %s is not expected to raise %s" % (operation, exc))
- raise
+ if getattr(ophandler, 'specialform', False):
+ retval = ophandler(*operation.args)
+ else:
+ vals = [self.getval(x) for x in operation.args]
+ if getattr(ophandler, 'need_result_type', False):
+ vals.insert(0, operation.result.concretetype)
+ try:
+ retval = ophandler(*vals)
+ except LLException, e:
+ # safety check check that the operation is allowed to raise that
+ # exception
+ if operation.opname in lloperation.LL_OPERATIONS:
+ canraise = lloperation.LL_OPERATIONS[operation.opname].canraise
+ if Exception not in canraise:
+ exc = self.llinterpreter.find_exception(e)
+ for canraiseexc in canraise:
+ if issubclass(exc, canraiseexc):
+ break
+ else:
+ raise TypeError("the operation %s is not expected to raise %s" % (operation, exc))
+ raise
self.setvar(operation.result, retval)
if tracer:
if retval is None:
@@ -857,6 +860,17 @@
except OverflowError:
self.make_llexception()
+ # read frame var support
+
+ def op_get_frame_base(self):
+ return llmemory.fakeaddress(self)
+
+ def op_get_frame_info(self, *vars):
+ return lltype.opaqueptr(llmemory.GCREF.TO,
+ 'frame_info',
+ vars=vars)
+ op_get_frame_info.specialform = True
+
#Operation of ootype
def op_new(self, INST):
Modified: pypy/dist/pypy/rpython/lltypesystem/lloperation.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lloperation.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lloperation.py Fri Jan 12 14:14:46 2007
@@ -428,6 +428,10 @@
'ooparse_int': LLOp(oo=True, canraise=(ValueError,)),
'ooparse_float': LLOp(oo=True, canraise=(ValueError,)),
'oohash': LLOp(oo=True, sideeffects=False),
+
+ # _____ read frame var support ___
+ 'get_frame_base': LLOp(),
+ 'get_frame_info': LLOp(),
}
# ***** Run test_lloperation after changes. *****
From guido at codespeak.net Fri Jan 12 14:51:20 2007
From: guido at codespeak.net (guido at codespeak.net)
Date: Fri, 12 Jan 2007 14:51:20 +0100 (CET)
Subject: [pypy-svn] r36572 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070112135120.07E841005A@code0.codespeak.net>
Author: guido
Date: Fri Jan 12 14:51:10 2007
New Revision: 36572
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
Log:
Food money 2007/01/12.
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt Fri Jan 12 14:51:10 2007
@@ -1,16 +1,16 @@
-Armin Rigo -10 -8 -8
-Anders Chrigstroem -10 -8 -8
-Samuele Pedroni -10 -8 -8
-Michael Hudson -10 -8 -8
-Niko Matsakis
-Antonio Cuni -10 -8 +8 -8
-Maciej Fijalkowski -10 -8 +110 -8
-Eric van Riet Paap -8
-Jacob Hallen -10 -8 -8
-Laura Creighton -10 -8 -8
+Armin Rigo -10 -8 -8 -8
+Anders Chrigstroem -10 -8 -8 -8
+Samuele Pedroni -10 -8 -8 -8
+Michael Hudson -10 -8 -8 -8
+Niko Matsakis -8
+Antonio Cuni -10 -8 +8 -8 -8
+Maciej Fijalkowski -10 -8 +110 -8 -8
+Eric van Riet Paap -8 -8
+Jacob Hallen -10 -8 -8 -8
+Laura Creighton -10 -8 -8 -8
Holger Krekel -10 -8 -8
-Carl Friedrich Bolz -10 -8 -8
-Guido Wesdorp -10 +134 -8 -8
-Leonardo Santagada -10 -8 -8
-Alexandre Fayolle -10 -8 +124 -8
-Sylvain Th?nault -10 -8 -
+Carl Friedrich Bolz -10 -8 -8 -8
+Guido Wesdorp -10 +134 -8 -8 +125
+Leonardo Santagada -10 -8 -8 -8
+Alexandre Fayolle -10 -8 +124 -8 -8
+Sylvain Th?nault -10 -8 -8 -8
From niko at codespeak.net Fri Jan 12 14:54:12 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Fri, 12 Jan 2007 14:54:12 +0100 (CET)
Subject: [pypy-svn] r36574 - in pypy/dist/pypy/translator/jvm: . src/pypy
Message-ID: <20070112135412.003E110074@code0.codespeak.net>
Author: niko
Date: Fri Jan 12 14:54:05 2007
New Revision: 36574
Modified:
pypy/dist/pypy/translator/jvm/builtin.py
pypy/dist/pypy/translator/jvm/database.py
pypy/dist/pypy/translator/jvm/generator.py
pypy/dist/pypy/translator/jvm/opcodes.py
pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
Log:
(antocuni, niko) fix it enough to run pystone translated
Modified: pypy/dist/pypy/translator/jvm/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/builtin.py (original)
+++ pypy/dist/pypy/translator/jvm/builtin.py Fri Jan 12 14:54:05 2007
@@ -41,8 +41,6 @@
# Look for a shortcut method in our table of remappings:
try:
key = (self.OOTYPE.__class__, methodnm)
- print "key=%r" % (key,)
- print "hash=%r" % (built_in_methods,)
return built_in_methods[key]
except KeyError: pass
Modified: pypy/dist/pypy/translator/jvm/database.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/database.py (original)
+++ pypy/dist/pypy/translator/jvm/database.py Fri Jan 12 14:54:05 2007
@@ -76,7 +76,14 @@
#
# Creates nodes that represents classes, functions, simple constants.
- def _types_for_graph(self, graph):
+ def types_for_graph(self, graph):
+ """
+ Given a graph, returns a tuple like so:
+ ( (java argument types...), java return type )
+ For example, if the graph took two strings and returned a bool,
+ then the return would be:
+ ( (jString, jString), jBool )
+ """
argtypes = [arg.concretetype for arg in graph.getargs()
if arg.concretetype is not ootype.Void]
jargtypes = tuple([self.lltype_to_cts(argty) for argty in argtypes])
@@ -90,7 +97,7 @@
Creates a node.Function object for a particular graph. Adds
the method to 'classobj', which should be a node.Class object.
"""
- jargtypes, jrettype = self._types_for_graph(graph)
+ jargtypes, jrettype = self.types_for_graph(graph)
funcobj = node.Function(
self, classobj, funcnm, jargtypes, jrettype, graph, is_static)
return funcobj
@@ -231,7 +238,7 @@
def record_delegate_impl(self, graph):
""" TYPE is a StaticMethod """
- jargtypes, jrettype = self._types_for_graph(graph)
+ jargtypes, jrettype = self.types_for_graph(graph)
key = (jargtypes, jrettype)
assert key in self._delegates
pfunc = self.pending_function(graph)
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Fri Jan 12 14:54:05 2007
@@ -911,7 +911,9 @@
self.prepare_generic_result(RETTYPE)
def call_primitive(self, graph):
- raise NotImplementedError
+ argtypes, rettype = self.db.types_for_graph(graph)
+ mthd = Method.s(jPyPy, graph.func.func_name, argtypes, rettype)
+ self.emit(mthd)
def call_oostring(self, OOTYPE):
cts_type = self.db.lltype_to_cts(OOTYPE)
@@ -1006,7 +1008,8 @@
elif value == 1.0:
self.emit(DCONST_1)
else:
- self.emit(LDC2, value)
+ # Big hack to avoid exponential notation:
+ self.emit(LDC2, "%22.22f" % value)
# __________________________________________________________________
# Methods invoked directly by strings in jvm/opcode.py
@@ -1092,7 +1095,7 @@
def _dbl_compare_op(self, cmpopcode):
# XXX --- NaN behavior?
- self._invoke(DCMPG)
+ self.emit(DCMPG)
self._compare_op(cmpopcode)
dbl_equals = lambda self: self._dbl_compare_op(IFEQ)
@@ -1103,7 +1106,7 @@
dbl_greater_equals = lambda self: self._dbl_compare_op(IFGE)
def _long_compare_op(self, cmpopcode):
- self._invoke(LCMP)
+ self.emit(LCMP)
self._compare_op(cmpopcode)
long_equals = lambda self: self._long_compare_op(IFEQ)
@@ -1194,6 +1197,9 @@
assert isinstance(lbl, Label)
self.curclass.out(' %s:\n' % lbl.jasmin_syntax())
+ # We count labels as instructions because ASM does:
+ self.curfunc.instr_counter += 1
+
def _instr(self, opcode, *args):
jvmstr, args = opcode.specialize(args)
def jasmin_syntax(arg):
Modified: pypy/dist/pypy/translator/jvm/opcodes.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/opcodes.py (original)
+++ pypy/dist/pypy/translator/jvm/opcodes.py Fri Jan 12 14:54:05 2007
@@ -33,7 +33,7 @@
'oodowncast': [DownCast, StoreResult],
'oois': 'ref_is_eq',
'oononnull': 'is_not_null',
- 'instanceof': CastTo,
+ 'instanceof': [CastTo, StoreResult],
'subclassof': [PushAllArgs, jvmgen.SWAP, jvmgen.CLASSISASSIGNABLEFROM, StoreResult],
'ooidentityhash': [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult],
'oohash': [PushAllArgs, jvmgen.OBJHASHCODE, StoreResult],
Modified: pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java
==============================================================================
--- pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java (original)
+++ pypy/dist/pypy/translator/jvm/src/pypy/PyPy.java Fri Jan 12 14:54:05 2007
@@ -425,7 +425,9 @@
public static ArrayList array_to_list(Object[] array)
{
- return new ArrayList(java.util.Arrays.asList(array));
+ ArrayList list = new ArrayList(java.util.Arrays.asList(array));
+ list.add(0, "dummy_executable_name");
+ return list;
}
// ----------------------------------------------------------------------
@@ -476,6 +478,24 @@
}
// ----------------------------------------------------------------------
+ // Primitive built-in functions
+
+ public static double ll_time_clock() {
+ return System.currentTimeMillis()/1000;
+ }
+
+ public static int ll_os_write(int fd, String text) {
+ // TODO: file descriptors, etc
+ if (fd == 1)
+ System.out.print(text);
+ else if (fd == 2)
+ System.err.print(text);
+ else
+ throw new RuntimeException("Invalid FD");
+ return text.length();
+ }
+
+ // ----------------------------------------------------------------------
// Exceptions
//
// If we don't use true Java exceptions, then this
@@ -523,6 +543,7 @@
}
public static void _ll_resize_le(ArrayList self, int length) {
+ System.err.println("ll_resize_le: self.size()="+self.size()+" length="+length);
while (self.size() > length) {
self.remove(self.size()-1);
}
@@ -532,8 +553,8 @@
if (length > self.size())
_ll_resize_ge(self, length);
else if (length < self.size())
- _ll_resize_le(self, length);
- }
+ _ll_resize_le(self, length);
+ }
// ----------------------------------------------------------------------
// Self Test
From fijal at codespeak.net Fri Jan 12 14:54:07 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 14:54:07 +0100 (CET)
Subject: [pypy-svn] r36573 - pypy/dist/pypy/translator
Message-ID: <20070112135407.DB32A10072@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 14:53:52 2007
New Revision: 36573
Modified:
pypy/dist/pypy/translator/translator.py
Log:
(arigo, fijal) Stick graphof as a private method of TranslationContext
Modified: pypy/dist/pypy/translator/translator.py
==============================================================================
--- pypy/dist/pypy/translator/translator.py (original)
+++ pypy/dist/pypy/translator/translator.py Fri Jan 12 14:53:52 2007
@@ -168,3 +168,5 @@
result.append(graph)
assert len(result) == 1
return result[0]
+
+TranslationContext._graphof = graphof
From pedronis at codespeak.net Fri Jan 12 15:14:12 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 12 Jan 2007 15:14:12 +0100 (CET)
Subject: [pypy-svn] r36575 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070112141412.AF2EB10082@code0.codespeak.net>
Author: pedronis
Date: Fri Jan 12 15:14:11 2007
New Revision: 36575
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
Log:
update report sketching meetings status
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/planning.txt Fri Jan 12 15:14:11 2007
@@ -124,10 +124,10 @@
Report outline writing
----------------------
- * Guido, Carl Friedrich, Alexandre: WP13
+ * Guido, Carl Friedrich, Alexandre: WP13 DONE
* Guido, Carl Friedrich, Maciek: WP2
* Arre, Maciek, Armin, Anto: WP12
- * Michael, Samuele, Carl Friedrich?: WP6
+ * Michael, Samuele, Carl Friedrich?: WP6 DONE
Discussions during the sprint
From antocuni at codespeak.net Fri Jan 12 15:47:38 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 15:47:38 +0100 (CET)
Subject: [pypy-svn] r36576 - pypy/dist/pypy/translator/backendopt
Message-ID: <20070112144738.22D071007D@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 15:47:29 2007
New Revision: 36576
Modified:
pypy/dist/pypy/translator/backendopt/malloc.py
Log:
Use the right TYPE for the key in newvarsmap; don't remove malloc of BuiltinType
Modified: pypy/dist/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/malloc.py Fri Jan 12 15:47:29 2007
@@ -49,6 +49,9 @@
def key_for_field_access(self, S, fldname):
raise NotImplementedError
+ def inline_type(self, TYPE):
+ raise NotImplementedError
+
def flowin(self, block, count, var, newvarsmap):
# in this 'block', follow where the 'var' goes to and replace
# it by a flattened-out family of variables. This family is given
@@ -186,6 +189,9 @@
op = cp[2]
if op.opname != self.MALLOC_OP:
return False
+ if not self.inline_type(op.args[0].value):
+ return False
+
lltypes[op.result.concretetype] = True
# there must be a single largest malloced GcStruct;
@@ -340,6 +346,9 @@
name = 'item%d' % (name,)
self.accessed_substructs[S, name] = True
+ def inline_type(self, TYPE):
+ return True
+
def equivalent_substruct(self, S, fieldname):
# we consider a pointer to a GcStruct S as equivalent to a
# pointer to a substructure 'S.fieldname' if it's the first
@@ -527,6 +536,9 @@
def RTTI_dtor(self, STRUCT):
return False
+ def inline_type(self, TYPE):
+ return isinstance(TYPE, (ootype.Record, ootype.Instance))
+
def _get_fields(self, TYPE):
if isinstance(TYPE, ootype.Record):
return TYPE._fields
@@ -537,7 +549,7 @@
def flatten(self, TYPE):
for name, (FIELDTYPE, default) in self._get_fields(TYPE).iteritems():
- key = TYPE, name
+ key = self.key_for_field_access(TYPE, name)
example = FIELDTYPE._defl()
constant = Constant(example)
constant.concretetype = FIELDTYPE
@@ -546,7 +558,8 @@
self.newvarstype[key] = FIELDTYPE
def key_for_field_access(self, S, fldname):
- return S, fldname
+ CLS, TYPE = S._lookup_field(fldname)
+ return CLS, fldname
def flowin_op(self, op, vars, newvarsmap):
if op.opname == "oogetfield":
From santagada at codespeak.net Fri Jan 12 15:47:42 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Fri, 12 Jan 2007 15:47:42 +0100 (CET)
Subject: [pypy-svn] r36577 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070112144742.54F7C1007D@code0.codespeak.net>
Author: santagada
Date: Fri Jan 12 15:47:29 2007
New Revision: 36577
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
break/continue working
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Fri Jan 12 15:47:29 2007
@@ -128,8 +128,24 @@
last = node.execute(ctx)
return last
except ExecutionReturned, e:
- return e.value
+ if e.type == 'return':
+ return e.value
+ else:
+ raise e
+
+class Unconditional(Statement):
+ def __init__(self, targtype, targlineno, targstart):
+ self.targtype = targtype
+ self.targlineno = targlineno
+ self.targstart = targstart
+
+class Break(Unconditional):
+ def execute(self, ctx):
+ raise ExecutionReturned('break', None, None)
+class Continue(Unconditional):
+ def execute(self, ctx):
+ raise ExecutionReturned('continue', None, None)
class Call(Expression):
def __init__(self, identifier, arglist):
@@ -419,7 +435,10 @@
last = node.execute(ctx)
return last
except ExecutionReturned, e:
- return e.value
+ if e.type == 'return':
+ return e.value
+ else:
+ raise e
class Semicolon(Statement):
def __init__(self, expr = None):
@@ -427,7 +446,7 @@
def execute(self, ctx):
if self.expr is None:
- return
+ return w_Undefined
return self.expr.execute(ctx)
class String(Expression):
@@ -445,7 +464,7 @@
self.expr = expr
def execute(self, ctx):
- raise ExecutionReturned(self.expr.eval(ctx))
+ raise ExecutionReturned('return', self.expr.eval(ctx), None)
class Throw(Statement):
def __init__(self, exception):
@@ -506,7 +525,13 @@
def execute(self, ctx):
while self.condition.eval(ctx).ToBoolean():
- self.body.execute(ctx)
+ try:
+ self.body.execute(ctx)
+ except ExecutionReturned, e:
+ if e.type == 'break':
+ break
+ elif e.type == 'continue':
+ continue
class For(Statement):
def __init__(self, setup, condition, update, body):
@@ -518,8 +543,14 @@
def execute(self, ctx):
self.setup.eval(ctx)
while self.condition.eval(ctx).ToBoolean():
- self.body.execute(ctx)
- self.update.eval(ctx)
+ try:
+ self.body.execute(ctx)
+ self.update.eval(ctx)
+ except ExecutionReturned, e:
+ if e.type == 'break':
+ break
+ elif e.type == 'continue':
+ continue
class Boolean(Expression):
def __init__(self, bool):
@@ -560,6 +591,9 @@
node = Assign(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'BLOCK':
node = Block(getlist(t))
+ elif tp == 'BREAK':
+ targtype, targlineno, targstart = gettreeitem(t, 'target').additional_info.split(',')
+ node = Break(targtype, targlineno, targstart)
elif tp == 'CALL':
node = Call(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'COMMA':
@@ -568,6 +602,9 @@
node = Conditional(from_tree(gettreeitem(t, '0')),
from_tree(gettreeitem(t, '1')),
from_tree(gettreeitem(t, '2')))
+ elif tp == 'CONTINUE':
+ targtype, targlineno, targstart = gettreeitem(t, 'target').additional_info.split(',')
+ node = Continue(targtype, targlineno, targstart)
elif tp == 'DOT':
node = Dot(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'EQ':
@@ -714,9 +751,8 @@
value = gettreeitem(t, 'type')
else:
value = gettreeitem(t, 'value').additional_info
-
-
- print tp
+
+
node.init_common(gettreeitem(t, 'type').additional_info, value,
int(gettreeitem(t, 'lineno').additional_info), start, end)
return node
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Fri Jan 12 15:47:29 2007
@@ -5,8 +5,10 @@
pass
class ExecutionReturned(Exception):
- def __init__(self, value):
+ def __init__(self, type='normal', value=None, identifier=None):
+ self.type = type
self.value = value
+ self.identifier = identifier
class ThrowException(Exception):
def __init__(self, exception):
@@ -30,7 +32,8 @@
self.Internal = Internal
def __repr__(self):
- return "|%s %d%d%d|"%(self.value, self.DontDelete, self.ReadOnly, self.DontEnum)
+ return "|%s %d%d%d|"%(self.value, self.DontDelete,
+ self.ReadOnly, self.DontEnum)
def internal_property(name, value):
"""return a internal property with the right attributes"""
@@ -58,7 +61,8 @@
def Get(self, P):
raise NotImplementedError
- def Put(self, P, V, DontDelete=False, ReadOnly=False, DontEnum=False, Internal=False):
+ def Put(self, P, V, DontDelete=False,
+ ReadOnly=False, DontEnum=False, Internal=False):
raise NotImplementedError
def PutValue(self, w, ctx):
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Fri Jan 12 15:47:29 2007
@@ -325,11 +325,13 @@
var tc = testcases.length;"""
def test_break(self):
- py.test.skip(" TODO: needed for mozilla test suite")
self.assert_prints("""
while(1){
break;
}
+ for(x=0;1==1;x++) {
+ break;
+ }
print('out')""", ["out"])
def test_typeof(self):
From fijal at codespeak.net Fri Jan 12 15:51:27 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 15:51:27 +0100 (CET)
Subject: [pypy-svn] r36578 - in pypy/dist/pypy/annotation: . test
Message-ID: <20070112145127.7FDAA10074@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 15:51:03 2007
New Revision: 36578
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/bookkeeper.py
pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
(arigo, fijal) Improve a test and rewrite a bit SomeGenericCallable, kill _known_annotation_
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Fri Jan 12 15:51:03 2007
@@ -685,12 +685,18 @@
class __extend__(pairtype(SomeGenericCallable, SomePBC)):
def union((gencall, pbc)):
- unique_key = (gencall, pbc.const)
- s_result = getbookkeeper().emulate_pbc_call(unique_key, pbc,
- gencall.args_s)
- assert gencall.s_result.contains(s_result)
+ unique_key = "unionof(SomeGenericCallable, SomePBC)"
+ if len(pbc.descriptions):
+ bk = pbc.descriptions.iterkeys().next().bookkeeper
+ s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s)
+ s_result = unionof(s_result, gencall.s_result)
+ assert gencall.s_result.contains(s_result)
return gencall
+class __extend__(pairtype(SomePBC, SomeGenericCallable)):
+ def union((pbc, gencall)):
+ return pair(gencall, pbc).union()
+
class __extend__(pairtype(SomeImpossibleValue, SomeObject)):
def union((imp1, obj2)):
return obj2
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Fri Jan 12 15:51:03 2007
@@ -391,10 +391,6 @@
elif extregistry.is_registered(x, self.policy):
entry = extregistry.lookup(x, self.policy)
result = entry.compute_annotation_bk(self)
-## elif hasattr(x, "compute_result_annotation"):
-## result = SomeBuiltin(x.compute_result_annotation, methodname=x.__name__)
-## elif hasattr(tp, "compute_annotation"):
-## result = tp.compute_annotation()
elif tp in EXTERNAL_TYPE_ANALYZERS:
result = SomeExternalObject(tp)
elif isinstance(x, lltype._ptr):
@@ -409,8 +405,6 @@
result = SomeOOClass(x._INSTANCE) # NB. can be None
elif isinstance(x, ootype.instance_impl): # XXX
result = SomeOOInstance(ootype.typeOf(x))
- elif hasattr(x, '_known_annotation_'):
- result = x._known_annotation_
elif callable(x):
if hasattr(x, '__self__') and x.__self__ is not None:
# for cases like 'l.append' where 'l' is a global constant list
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Fri Jan 12 15:51:03 2007
@@ -2451,45 +2451,30 @@
assert s.const == 0
def test_some_generic_function_call(self):
- def g(a):
- pass
- g._known_annotation_ = annmodel.SomeGenericCallable(
- args=(annmodel.SomeInteger(),), result=annmodel.SomeInteger())
+ def h(x):
+ return int(x)
- def fun():
- return g(1)
-
- a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
- s = a.build_types(fun, [])
- assert isinstance(s, annmodel.SomeInteger)
- assert not hasattr(s, 'const')
-
- def test_some_generic_function_callback(self):
- def g(a):
- pass
- g._known_annotation_ = annmodel.SomeGenericCallable(
- args=[annmodel.SomeGenericCallable(args=[annmodel.SomeInteger()],
- result=annmodel.SomeInteger())],
- result=annmodel.SomeInteger())
+ def c(x):
+ return int(x)
+
+ def g(a, x):
+ if x == -1:
+ a = None
+ if x < 0:
+ if x == -1:
+ a = h
+ else:
+ a = c
+ return a(x)
- def fun2(x):
- return x
+ #def fun(x):
- def fun():
- return g(fun2)
-
a = self.RPythonAnnotator(policy=policy.AnnotatorPolicy())
- s = a.build_types(fun, [])
+ s = a.build_types(g, [annmodel.SomeGenericCallable(
+ args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()),
+ annmodel.SomeFloat()])
assert isinstance(s, annmodel.SomeInteger)
- graphs = a.annotated.values()
- found = False
- for graph in graphs:
- if graph.name == "fun2":
- found = True
- inputcells = graph.startblock.inputargs
- assert len(inputcells) == 1
- assert isinstance(a.bindings[inputcells[0]], annmodel.SomeInteger)
- assert found
+ assert not hasattr(s, 'const')
def g(n):
return [0,1,2,n]
From cfbolz at codespeak.net Fri Jan 12 15:52:17 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 15:52:17 +0100 (CET)
Subject: [pypy-svn] r36579 - pypy/dist/pypy/translator/cli
Message-ID: <20070112145217.8005010074@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 15:52:15 2007
New Revision: 36579
Modified:
pypy/dist/pypy/translator/cli/cts.py
pypy/dist/pypy/translator/cli/ilgenerator.py
pypy/dist/pypy/translator/cli/metavm.py
Log:
(cfbolz, antocuni reviewing): try to make the name-only static methods work
with cli.
Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py (original)
+++ pypy/dist/pypy/translator/cli/cts.py Fri Jan 12 15:52:15 2007
@@ -208,6 +208,19 @@
return '%s %s(%s)' % (ret_type, func_name, arg_list)
+ def op_to_signature(self, op, func_name):
+ ret_type, ret_var = self.llvar_to_cts(op.result)
+ func_name = self.escape_name(func_name)
+
+ args = [arg for arg in op.args[1:]
+ if arg.concretetype is not ootype.Void]
+
+ arg_types = [self.lltype_to_cts(arg.concretetype) for arg in args]
+ arg_list = ', '.join(arg_types)
+
+ return '%s %s(%s)' % (ret_type, func_name, arg_list)
+
+
def method_signature(self, TYPE, name_or_desc):
# TODO: use callvirt only when strictly necessary
if isinstance(TYPE, ootype.Instance):
Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py (original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py Fri Jan 12 15:52:15 2007
@@ -283,6 +283,9 @@
def function_signature(self, graph, func_name=None):
return self.cts.graph_to_signature(graph, False, func_name)
+ def op_signature(self, op, func_name):
+ return self.cts.op_to_signature(op, func_name)
+
def class_name(self, TYPE):
if isinstance(TYPE, ootype.Instance):
return self.db.class_name(TYPE)
@@ -298,6 +301,10 @@
func_sig = self.function_signature(graph, func_name)
self.ilasm.call(func_sig)
+ def call_op(self, op, func_name):
+ func_sig = self.op_signature(op, func_name)
+ self.ilasm.call(func_sig)
+
def call_signature(self, signature):
self.ilasm.call(signature)
Modified: pypy/dist/pypy/translator/cli/metavm.py
==============================================================================
--- pypy/dist/pypy/translator/cli/metavm.py (original)
+++ pypy/dist/pypy/translator/cli/metavm.py Fri Jan 12 15:52:15 2007
@@ -13,13 +13,16 @@
callee = op.args[0].value
if isinstance(callee, _static_meth):
self._render_native_function(generator, callee, op.args)
- else:
+ elif hasattr(callee, "graph"):
graph = callee.graph
method_name = oopspec.get_method_name(graph, op)
if method_name is None:
self._render_function(generator, graph, op.args)
else:
self._render_method(generator, method_name, op.args[1:])
+ else:
+ self._render_primitive_function(generator, callee, op)
+
def _load_arg_or_null(self, generator, arg):
if arg.concretetype is ootype.Void:
@@ -86,6 +89,13 @@
method_name == 'll_current_value':
generator.ilasm.pop()
+ def _render_primitive_function(self, generator, callee, op):
+ for func_arg in op.args[1:]: # push parameters
+ self._load_arg_or_null(generator, func_arg)
+ module, name = callee._name.split(".")
+ func_name = '[pypylib]pypy.builtin.%s::%s' % (module, name)
+ generator.call_op(op, func_name)
+
class _CallMethod(_Call):
def render(self, generator, op):
method = op.args[0]
From fijal at codespeak.net Fri Jan 12 15:53:03 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 15:53:03 +0100 (CET)
Subject: [pypy-svn] r36580 - pypy/dist/pypy/rpython/test
Message-ID: <20070112145303.B154E1007D@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 15:52:59 2007
New Revision: 36580
Modified:
pypy/dist/pypy/rpython/test/test_extfunc.py
Log:
Add passing test
Modified: pypy/dist/pypy/rpython/test/test_extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_extfunc.py (original)
+++ pypy/dist/pypy/rpython/test/test_extfunc.py Fri Jan 12 15:52:59 2007
@@ -49,3 +49,27 @@
res = interpret(f, [])
assert res == 7
+
+def d(y):
+ return eval("y()")
+
+class DTestFuncEntry(ExtFuncEntry):
+ _about_ = d
+ name = 'd'
+ signature_args = [annmodel.SomeGenericCallable(args=[], result=
+ annmodel.SomeFloat())]
+ signature_result = annmodel.SomeFloat()
+
+def test_callback():
+ def callback():
+ return 2.5
+
+ def f():
+ return d(callback)
+
+ policy = AnnotatorPolicy()
+ policy.allow_someobjects = False
+ a = RPythonAnnotator(policy=policy)
+ s = a.build_types(f, [])
+ assert isinstance(s, annmodel.SomeFloat)
+ assert a.translator._graphof(callback)
From santagada at codespeak.net Fri Jan 12 15:54:30 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Fri, 12 Jan 2007 15:54:30 +0100 (CET)
Subject: [pypy-svn] r36581 - pypy/dist/pypy/lang/js/test
Message-ID: <20070112145430.B751E10074@code0.codespeak.net>
Author: santagada
Date: Fri Jan 12 15:53:56 2007
New Revision: 36581
Modified:
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
multiple assignment "x = z =y" working... for free!
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Fri Jan 12 15:53:56 2007
@@ -336,6 +336,10 @@
def test_typeof(self):
py.test.skip(" TODO: needed for mozilla test suite")
+ self.assert_prints("""
+ var x = 3
+ typeof x ==
+ """)
def test_switch(self):
py.test.skip(" TODO: needed for mozilla test suite")
@@ -369,6 +373,12 @@
print(!x)
print(!!x)""", ["true", "false"])
+ def test_equals(self):
+ self.assert_prints("""
+ var x = 5;
+ y = z = x
+ print(y)""", ["5"])
+
def test_smallthings(self):
py.test.skip(" TODO: needed for mozilla test suite")
x = """
@@ -382,4 +392,3 @@
return ( Number.NaN );"""
x = "Number.POSITIVE_INFINITY Number.NEGATIVE_INFINITY"
x = "Math.floor( Math.abs( t ) ) );"
- x = "this.orig.werror = this.werror = false;"
\ No newline at end of file
From cfbolz at codespeak.net Fri Jan 12 15:55:21 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 15:55:21 +0100 (CET)
Subject: [pypy-svn] r36582 - pypy/dist/pypy/rpython/module
Message-ID: <20070112145521.A94B01007D@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 15:55:12 2007
New Revision: 36582
Modified:
pypy/dist/pypy/rpython/module/ll_os.py
Log:
give names that gencli understand. this repetition of the namespace should be
fixed.
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jan 12 15:55:12 2007
@@ -37,7 +37,7 @@
class ExecvFuncEntry(ExtFuncEntry):
_about_ = os.execv
- name = "ll_os_execv"
+ name = "ll_os.ll_os_execv"
signature_args = [SomeString(), s_list_of_strings]
signature_result = s_ImpossibleValue
@@ -62,7 +62,7 @@
class DupFuncEntry(ExtFuncEntry):
_about_ = os.dup
- name = "ll_os_dup"
+ name = "ll_os.ll_os_dup"
signature_args = [SomeInteger()]
signature_result = SomeInteger()
@@ -78,7 +78,7 @@
class Dup2FuncEntry(ExtFuncEntry):
_about_ = os.dup2
- name = "ll_os_dup2"
+ name = "ll_os.ll_os_dup2"
signature_args = [SomeInteger(), SomeInteger()]
signature_result = s_None
From cfbolz at codespeak.net Fri Jan 12 15:56:20 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 15:56:20 +0100 (CET)
Subject: [pypy-svn] r36583 - pypy/dist/pypy/module/posix
Message-ID: <20070112145620.529C71007D@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 15:56:19 2007
New Revision: 36583
Modified:
pypy/dist/pypy/module/posix/__init__.py
Log:
execve is disabled currently
Modified: pypy/dist/pypy/module/posix/__init__.py
==============================================================================
--- pypy/dist/pypy/module/posix/__init__.py (original)
+++ pypy/dist/pypy/module/posix/__init__.py Fri Jan 12 15:56:19 2007
@@ -84,8 +84,9 @@
space = self.space
config = space.config
# XXX execve does not work under ootypesystem yet :-(
- if config.translating and config.translation.type_system != "lltype":
- space.delattr(self, space.wrap("execve"))
+ # YYY nor does it anywhere else
+ #if config.translating and config.translation.type_system != "lltype":
+ # space.delattr(self, space.wrap("execve"))
for constant in dir(os):
value = getattr(os, constant)
From mwh at codespeak.net Fri Jan 12 16:01:36 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Fri, 12 Jan 2007 16:01:36 +0100 (CET)
Subject: [pypy-svn] r36584 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070112150136.6838910074@code0.codespeak.net>
Author: mwh
Date: Fri Jan 12 16:01:09 2007
New Revision: 36584
Modified:
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/regalloc.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
reorganizations to only emit the stack adjustment code when we need it.
this probably makes the generated code quite a bit faster but more importantly
right now it's much easier to follow.
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Fri Jan 12 16:01:09 2007
@@ -300,7 +300,7 @@
self.targetbuilder.initial_var2loc = {}
for gv_arg in self.jump_args_gv:
self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
- self.targetbuilder.initial_spill_offset = allocator.spill_offset
+ allocator.builders_to_tell_spill_offset_to.append(self.targetbuilder)
def emit(self, asm):
if self.targetbuilder.start:
asm.load_word(rSCRATCH, self.targetbuilder.start)
@@ -394,6 +394,20 @@
self.result_regclass = NO_REGISTER
self.result = None
+class Move(AllocTimeInsn):
+ def __init__(self, dest, src):
+ self.dest = dest
+ self.src = src
+ def emit(self, asm):
+ asm.mr(self.dest.number, self.src.number)
+
+class Load(AllocTimeInsn):
+ def __init__(self, dest, const):
+ self.dest = dest
+ self.const = const
+ def emit(self, asm):
+ self.const.load_now(asm, self.dest)
+
class Unspill(AllocTimeInsn):
""" A special instruction inserted by our register "allocator." It
indicates that we need to load a value from the stack into a register
Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/regalloc.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py Fri Jan 12 16:01:09 2007
@@ -40,6 +40,7 @@
# crfinfo is a bit of a hack used to transmit which bit a compare
# instruction set to the branch instruction
self.crfinfo = [(0, 0)] * 8
+ self.builders_to_tell_spill_offset_to = []
def set(self, var, loc):
assert var not in self.var2loc
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Jan 12 16:01:09 2007
@@ -104,28 +104,33 @@
class JumpPatchupGenerator(object):
- def __init__(self, asm, min_offset):
- self.asm = asm
+ def __init__(self, insns, min_offset):
+ self.insns = insns
self.min_offset = min_offset
def emit_move(self, tarloc, srcloc):
if tarloc == srcloc: return
+ emit = self.insns.append
if tarloc.is_register and srcloc.is_register:
- self.asm.mr(tarloc.number, srcloc.number)
+ emit(insn.Move(tarloc, srcloc))
elif tarloc.is_register and not srcloc.is_register:
- self.asm.lwz(tarloc.number, rFP, srcloc.offset)
+ emit(insn.Unspill(None, tarloc, srcloc))
+ #self.asm.lwz(tarloc.number, rFP, srcloc.offset)
elif not tarloc.is_register and srcloc.is_register:
- self.asm.stw(srcloc.number, rFP, tarloc.offset)
+ emit(insn.Spill(None, srcloc, tarloc))
+ #self.asm.stw(srcloc.number, rFP, tarloc.offset)
elif not tarloc.is_register and not srcloc.is_register:
- self.asm.lwz(rSCRATCH, rFP, srcloc.offset)
- self.asm.stw(rSCRATCH, rFP, tarloc.offset)
+ emit(insn.Unspill(None, insn.gprs[0], srcloc))
+ emit(insn.Spill(None, insn.gprs[0], tarloc))
+ #self.asm.lwz(rSCRATCH, rFP, srcloc.offset)
+ #self.asm.stw(rSCRATCH, rFP, tarloc.offset)
def create_fresh_location(self):
r = self.min_offset
self.min_offset -= 4
return insn.stack_slot(r)
-def prepare_for_jump(asm, min_offset, sourcevars, src2loc, target):
+def prepare_for_jump(insns, min_offset, sourcevars, src2loc, target):
tar2src = {} # tar var -> src var
tar2loc = {}
@@ -140,9 +145,9 @@
tar2loc[tloc] = tloc
tar2src[tloc] = src
else:
- src.load_now(asm, tloc)
+ insns.append(insn.Load(tloc, src))
- gen = JumpPatchupGenerator(asm, min_offset)
+ gen = JumpPatchupGenerator(insns, min_offset)
emit_moves(gen, tar2src, tar2loc, src2loc)
return gen.min_offset
@@ -386,7 +391,6 @@
#print 'final initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
self.initial_spill_offset = min_stack_offset
target_addr = self.asm.mc.tell()
- self.emit_stack_adjustment()
return Label(target_addr, arg_locations, min_stack_offset)
def jump_if_false(self, gv_condition, args_gv):
@@ -420,11 +424,11 @@
self._close()
def finish_and_goto(self, outputargs_gv, target):
- allocator = self.allocate_and_emit(outputargs_gv)
+ allocator = self.allocate(outputargs_gv)
min_offset = min(allocator.spill_offset, target.min_stack_offset)
- min_offset = prepare_for_jump(
- self.asm, min_offset, outputargs_gv, allocator.var2loc, target)
- self.patch_stack_adjustment(self._stack_size(min_offset))
+ allocator.spill_offset = prepare_for_jump(
+ self.insns, min_offset, outputargs_gv, allocator.var2loc, target)
+ self.emit(allocator)
self.asm.load_word(rSCRATCH, target.startaddr)
self.asm.mtctr(rSCRATCH)
self.asm.bctr()
@@ -453,12 +457,10 @@
self.asm.mc = self.rgenop.ExistingCodeBlock(self.final_jump_addr, self.final_jump_addr+8)
self.asm.load_word(rSCRATCH, target)
self.asm.mc = mc
- self.emit_stack_adjustment()
return self
else:
self._open()
self.maybe_patch_start_here()
- self.emit_stack_adjustment()
return self
def maybe_patch_start_here(self):
@@ -533,8 +535,6 @@
# save stack pointer into linkage area and set stack pointer for us.
self.asm.stwu(rSP, rSP, -minspace)
- self.emit_stack_adjustment()
-
return inputargs
def _var_offset(self, v):
@@ -562,17 +562,28 @@
self.asm.mc = None
def allocate_and_emit(self, live_vars_gv):
+ allocator = self.allocate(live_vars_gv)
+ return self.emit(allocator)
+
+ def allocate(self, live_vars_gv):
assert self.initial_var2loc is not None
allocator = RegisterAllocation(
- self.rgenop.freeregs, self.initial_var2loc, self.initial_spill_offset)
+ self.rgenop.freeregs,
+ self.initial_var2loc,
+ self.initial_spill_offset)
self.insns = allocator.allocate_for_insns(self.insns)
- #if self.insns:
- self.patch_stack_adjustment(self._stack_size(allocator.spill_offset))
+ return allocator
+
+ def emit(self, allocator):
+ if allocator.spill_offset < self.initial_spill_offset:
+ self.emit_stack_adjustment(self._stack_size(allocator.spill_offset))
for insn in self.insns:
insn.emit(self.asm)
+ for builder in allocator.builders_to_tell_spill_offset_to:
+ builder.initial_spill_offset = allocator.spill_offset
return allocator
- def emit_stack_adjustment(self):
+ def emit_stack_adjustment(self, newsize):
# the ABI requires that at all times that r1 is valid, in the
# sense that it must point to the bottom of the stack and that
# executing SP <- *(SP) repeatedly walks the stack.
@@ -587,7 +598,7 @@
# crf0 (a very small chance of being a problem)
self.stack_adj_addr = self.asm.mc.tell()
#print "emit_stack_adjustment at: ", self.stack_adj_addr
- self.asm.addi(rSCRATCH, rFP, 0) # this is the immediate that later gets patched
+ self.asm.addi(rSCRATCH, rFP, -newsize)
self.asm.subx(rSCRATCH, rSCRATCH, rSP) # rSCRATCH should now be <= 0
self.asm.beq(3) # if rSCRATCH == 0, there is no actual adjustment, so
# don't end up with the situation where *(rSP) == rSP
@@ -595,15 +606,15 @@
self.asm.stw(rFP, rSP, 0)
# branch to "here"
- def patch_stack_adjustment(self, newsize):
- if self.stack_adj_addr == 0:
- return
- #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
- # we build an addi instruction by hand here
- mc = self.asm.mc
- self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
- self.asm.addi(rSCRATCH, rFP, -newsize)
- self.asm.mc = mc
+## def patch_stack_adjustment(self, newsize):
+## if self.stack_adj_addr == 0:
+## return
+## #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
+## # we build an addi instruction by hand here
+## mc = self.asm.mc
+## self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
+## self.asm.addi(rSCRATCH, rFP, -newsize)
+## self.asm.mc = mc
def _arg_op(self, gv_arg, opcode):
gv_result = Var()
From ericvrp at codespeak.net Fri Jan 12 16:02:42 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 12 Jan 2007 16:02:42 +0100 (CET)
Subject: [pypy-svn] r36585 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070112150242.063B410080@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 12 16:02:37 2007
New Revision: 36585
Modified:
pypy/dist/pypy/jit/codegen/llvm/compatibility.py
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
Log:
(ericvrp, arigo around)
fix *Const classes, more tests passing.
Modified: pypy/dist/pypy/jit/codegen/llvm/compatibility.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/compatibility.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/compatibility.py Fri Jan 12 16:02:37 2007
@@ -29,4 +29,5 @@
i32 = 'i32'
i64 = 'i64'
+i1 = 'bool'
f64 = 'double'
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Fri Jan 12 16:02:37 2007
@@ -8,7 +8,7 @@
from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr
from pypy.jit.codegen.llvm.conftest import option
from pypy.jit.codegen.llvm.compatibility import icmp, scmp, ucmp, fcmp, inttoptr,\
- trunc, zext, bitcast, shr_prefix, define, i8, i16, i32, f64
+ trunc, zext, bitcast, shr_prefix, define, i1, i8, i16, i32, f64
pi8 = i8 + '*'
@@ -95,52 +95,56 @@
count.n_vars += 1
def operand(self):
- return '%s %%v%d' % (self.type, self.n)
+ return '%s %s' % (self.type, self.operand2())
def operand2(self):
return '%%v%d' % (self.n,)
class GenericConst(GenConst):
- #type = 'generic'
-
- #def __init__(self, value):
- # self.value = value
def operand(self):
- return '%s %s' % (self.type, self.value)
-
- def operand2(self):
- return str(self.value)
+ return '%s %s' % (self.type, self.operand2())
@specialize.arg(1)
def revealconst(self, T):
if isinstance(T, lltype.Ptr):
- return lltype.cast_int_to_ptr(T, self.value)
+ return lltype.cast_int_to_ptr(T, self.get_integer_value())
elif T is llmemory.Address:
- return llmemory.cast_int_to_adr(self.value)
+ return llmemory.cast_int_to_adr(self.get_integer_value())
else:
- return lltype.cast_primitive(T, self.value)
+ return lltype.cast_primitive(T, self.get_integer_value())
class BoolConst(GenericConst):
- type = 'bool'
+ type = i1
signed = False
def __init__(self, value):
self.value = bool(value)
+ def operand2(self):
+ if self.value:
+ return 'true'
+ else:
+ return 'false'
+
+ def get_integer_value(self):
+ return int(self.value)
+
class CharConst(GenericConst):
type = i8
signed = False
def __init__(self, value):
- if type(value) is str:
- self.value = ord(value)
- else:
- assert type(value) is int
- self.value = value
+ self.value = ord(value)
+
+ def operand2(self):
+ return '%d' % self.value
+
+ def get_integer_value(self):
+ return self.value
class UniCharConst(GenericConst):
@@ -150,6 +154,12 @@
def __init__(self, value):
self.value = unicode(value)
+ def operand2(self):
+ return '%s' % self.value
+
+ def get_integer_value(self):
+ return int(self.value)
+
class IntConst(GenericConst):
type = i32
@@ -158,12 +168,11 @@
def __init__(self, value):
self.value = int(value)
- #XXX why does typeof value change in test_genc_ts.py -k test_degenerated_before_return(_2)?
- def operand(self):
- return '%s %d' % (self.type, int(self.value))
-
def operand2(self):
- return str(int(self.value))
+ return str(self.value)
+
+ def get_integer_value(self):
+ return self.value
class UIntConst(GenericConst):
@@ -173,6 +182,12 @@
def __init__(self, value):
self.value = int(value)
+ def operand2(self):
+ return str(self.value)
+
+ def get_integer_value(self):
+ return self.value
+
class FloatConst(GenericConst):
type = f64
@@ -181,6 +196,14 @@
def __init__(self, value):
self.value = float(value)
+ def operand2(self):
+ return str(self.value)
+
+ @specialize.arg(1)
+ def revealconst(self, T):
+ assert T is lltype.Float
+ return self.value
+
class AddrConst(GenConst):
type = pi8
@@ -190,10 +213,13 @@
self.addr = addr
def operand(self):
- return '%s %s' % (self.type, llmemory.cast_adr_to_int(self.addr))
+ return '%s %s' % (self.type, self.operand2())
def operand2(self):
- return str(llmemory.cast_adr_to_int(self.addr))
+ s = str(llmemory.cast_adr_to_int(self.addr))
+ if s == '0':
+ s = 'null'
+ return s
@specialize.arg(1)
def revealconst(self, T):
@@ -435,52 +461,52 @@
def op_float_neg(self, gv_x): return self._rgenop2_generic('sub', FloatConst(0.0), gv_x)
def op_int_lt(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'lt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'lt', gv_x, gv_y, i1)
def op_int_le(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'le', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'le', gv_x, gv_y, i1)
def op_int_eq(self, gv_x, gv_y):
- return self._rgenop2_generic(icmp + 'eq' , gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(icmp + 'eq' , gv_x, gv_y, i1)
def op_int_ne(self, gv_x, gv_y):
- return self._rgenop2_generic(icmp + 'ne' , gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(icmp + 'ne' , gv_x, gv_y, i1)
def op_int_gt(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'gt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'gt', gv_x, gv_y, i1)
def op_int_ge(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'ge', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'ge', gv_x, gv_y, i1)
def op_uint_lt(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'lt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'lt', gv_x, gv_y, i1)
def op_uint_le(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'le', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'le', gv_x, gv_y, i1)
def op_uint_gt(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'gt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'gt', gv_x, gv_y, i1)
def op_uint_ge(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'ge', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'ge', gv_x, gv_y, i1)
def op_float_lt(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'lt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'lt', gv_x, gv_y, i1)
def op_float_le(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'le', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'le', gv_x, gv_y, i1)
def op_float_eq(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'eq', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'eq', gv_x, gv_y, i1)
def op_float_ne(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'ne', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'ne', gv_x, gv_y, i1)
def op_float_gt(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'gt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'gt', gv_x, gv_y, i1)
def op_float_ge(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'ge', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'ge', gv_x, gv_y, i1)
op_unichar_eq = op_ptr_eq = op_uint_eq = op_int_eq
op_unichar_ne = op_ptr_ne = op_uint_ne = op_int_ne
@@ -506,10 +532,10 @@
def op_uint_invert(self, gv_x): return self._rgenop2_generic('xor', gv_x, UIntConst((1<<32)-1))
def _abs(self, gv_x, nullstr='0'):
- gv_comp = Var('bool')
+ gv_comp = Var(i1)
gv_abs_pos = Var(gv_x.type)
gv_result = Var(gv_x.type)
- if nullstr is '0':
+ if nullstr == '0':
l = ' %s=' + scmp + 'ge %s,%s'
else:
l = ' %s=' + fcmp + 'ge %s,%s'
@@ -554,14 +580,14 @@
gv_result.operand2(), trunc, gv_x.operand(), restype))
return gv_result
- def _cast_to_bool(self, gv_x): return self._cast_to(gv_x, 'bool')
+ def _cast_to_bool(self, gv_x): return self._cast_to(gv_x, i1)
def _cast_to_char(self, gv_x): return self._cast_to(gv_x, i8)
def _cast_to_unichar(self, gv_x): return self._cast_to(gv_x, i32)
def _cast_to_int(self, gv_x): return self._cast_to(gv_x, i32)
def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, u32)
def _cast_to_float(self, gv_x): return self._cast_to(gv_x, f64)
- def _trunc_to_bool(self, gv_x): return self._trunc_to(gv_x, 'bool')
+ def _trunc_to_bool(self, gv_x): return self._trunc_to(gv_x, i1)
def _trunc_to_char(self, gv_x): return self._trunc_to(gv_x, i8)
def _trunc_to_unichar(self, gv_x): return self._trunc_to(gv_x, i32)
def _trunc_to_int(self, gv_x): return self._trunc_to(gv_x, i32)
@@ -647,8 +673,8 @@
def _is_false(self, gv_x, nullstr='0'):
log('%s Builder._is_false %s' % (self.block.label, gv_x.operand()))
- gv_result = Var('bool')
- if nullstr is '0':
+ gv_result = Var(i1)
+ if nullstr == '0':
l = ' %s=' + icmp + 'eq %s,%s'
else:
l = ' %s=' + fcmp + 'eq %s,%s'
@@ -657,8 +683,8 @@
def _is_true(self, gv_x, nullstr='0'):
log('%s Builder._is_true %s' % (self.block.label, gv_x.operand()))
- gv_result = Var('bool')
- if nullstr is '0':
+ gv_result = Var(i1)
+ if nullstr == '0':
l = ' %s=' + icmp + 'ne %s,%s'
else:
l = ' %s=' + fcmp + 'ne %s,%s'
@@ -705,8 +731,8 @@
self.block.label, offset, fieldtype, gv_ptr.operand()))
gv_ptr_var = self._as_var(gv_ptr)
gv_sub = Var(gv_ptr.type)
- self.asm.append(' %s=getelementptr %s,%d' % (
- gv_sub.operand2(), gv_ptr_var.operand(), offset))
+ self.asm.append(' %s=getelementptr %s,%s %d' % (
+ gv_sub.operand2(), gv_ptr_var.operand(), i32, offset))
return gv_sub
def genop_getarraysubstruct(self, arraytoken, gv_ptr, gv_index):
@@ -716,20 +742,27 @@
self.mc.LEA(eax, op)
return self.returnvar(eax)
'''
- #XXX TODO
- array_length_offset, array_items_offset, item_size, item_type = arraytoken
- gv_result = Var(i32)
+ #XXX WIP
log('%s Builder.genop_getarraysubstruct %s,%s,%s' % (
- self.block.label, arraytoken, gv_ptr, gv_index))
- self.asm.append(' %s=%s 0 ;%s Builder.genop_getarraysubstruct %s,%s,%s' % (
- gv_result.operand2(), gv_result.type, self.block.label, arraytoken, gv_ptr, gv_index))
+ self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
+
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
+
+ op_size = self._itemaddr(arraytoken, gv_index)
+
+ gv_ptr_var = self._as_var(gv_ptr)
+
+ gv_result = Var(pi8)
+ self.asm.append(' %s=getelementptr %s,%s' % (
+ gv_result.operand2(), gv_ptr_var.operand(), op_size.operand()))
+
return gv_result
def genop_getarraysize(self, arraytoken, gv_ptr):
- array_length_offset, array_items_offset, item_size, item_type = arraytoken
log('%s Builder.genop_getarraysize %s,%s' % (
self.block.label, arraytoken, gv_ptr.operand()))
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
gv_ptr_var = self._as_var(gv_ptr)
gv_p = Var(gv_ptr_var.type)
@@ -799,9 +832,8 @@
def genop_malloc_fixedsize(self, size):
log('%s Builder.genop_malloc_fixedsize %s' % (
self.block.label, str(size)))
- t = pi8
- gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
- gv_result = Var(t)
+ gv_gc_malloc_fnaddr = Var('%s (%s)*' % (pi8, i32))
+ gv_result = Var(pi8)
#or use addGlobalFunctionMapping in libllvmjit.restart()
self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr' % (
gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
@@ -810,6 +842,19 @@
gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), i32, size))
return gv_result
+ def _itemaddr(self, arraytoken, gv_index):
+ length_offset, items_offset, item_size, item_type = arraytoken
+
+ gv_size2 = Var(i32) #i386 uses self.itemaddr here
+ self.asm.append(' %s=mul %s,%d' % (
+ gv_size2.operand2(), gv_index.operand(), item_size))
+
+ gv_size3 = Var(i32)
+ self.asm.append(' %s=add %s,%d' % (
+ gv_size3.operand2(), gv_size2.operand(), items_offset))
+
+ return gv_size3
+
def genop_malloc_varsize(self, varsizealloctoken, gv_size):
log('%s Builder.genop_malloc_varsize %s,%s' % (
self.block.label, varsizealloctoken, gv_size.operand()))
@@ -822,17 +867,11 @@
gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
- gv_size2 = Var(i32) #i386 uses self.itemaddr here
- self.asm.append(' %s=mul %s,%d' % (
- gv_size2.operand2(), gv_size.operand(), item_size))
-
- gv_size3 = Var(i32)
- self.asm.append(' %s=add %s,%d' % (
- gv_size3.operand2(), gv_size2.operand(), items_offset))
+ op_size = self._itemaddr(varsizealloctoken, gv_size)
gv_result = Var(pi8)
self.asm.append(' %s=call %s(%s)' % (
- gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), gv_size3.operand()))
+ gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), op_size.operand()))
gv_p = Var(gv_result.type)
self.asm.append(' %s=getelementptr %s,%s %s' % (
@@ -850,15 +889,15 @@
log('%s Builder.genop_call %s,%s,%s' % (
self.block.label, sigtoken, gv_fnptr, [v.operand() for v in args_gv]))
argtypes, restype = sigtoken
- gv_returnvar = Var(restype)
if isinstance(gv_fnptr, AddrConst):
- gv_fn = Var(self._funcsig_type(args_gv, restype))
- self.asm.append(' %s=%s %s to %s' % (
- gv_fnptr.operand2(), bitcast, gv_fnptr.operand(), gv_fn.type))
+ gv_fn = Var(self._funcsig_type(args_gv, restype) + '*')
+ self.asm.append(' %s=%s %s %s to %s' % (
+ gv_fn.operand2(), bitcast, i32, gv_fnptr.operand2(), gv_fn.type))
funcsig = gv_fn.operand()
else:
#XXX we probably need to call an address directly if we can't resolve the funcsig
funcsig = self.rgenop.funcsig[gv_fnptr.value]
+ gv_returnvar = Var(restype)
self.asm.append(' %s=call %s(%s)' % (
gv_returnvar.operand2(),
funcsig,
@@ -873,6 +912,7 @@
def finish_and_goto(self, outputargs_gv, target):
# 'target' is a label, which for the llvm backend is a Block
+ log('%s Builder.finish_and_goto' % self.block.label)
gv = [v.operand() for v in outputargs_gv]
log('%s Builder.finish_and_goto %s,%s' % (
self.block.label, gv, target.label))
@@ -988,7 +1028,7 @@
if isinstance(T, lltype.Ptr) or T is llmemory.Address:
return pi8
elif T is lltype.Bool:
- return 'bool'
+ return i1
elif T is lltype.Char:
return i8
elif T is lltype.Unsigned:
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Fri Jan 12 16:02:37 2007
@@ -29,6 +29,8 @@
if llvm_version() < 2.0:
test_loop_merging = skip_too_minimal #segfault
test_two_loops_merging = skip_too_minimal #segfault
+ test_green_char_at_merge = skip #segfault
+ test_residual_red_call_with_exc = skip
if skip_passing:
test_very_simple = skip
@@ -67,23 +69,18 @@
test_red_propagate = skip
test_red_subcontainer = skip
test_red_subcontainer_cast = skip
- test_merge_structures = skip
- test_simple_meth = skip
- test_simple_red_meth = skip
test_degenerated_at_return = skip
test_degenerate_with_voids = skip
test_red_array = skip
-
- #failing...
- if skip_failing:
test_red_struct_array = skip
test_red_varsized_struct = skip
test_array_of_voids = skip
test_green_with_side_effects = skip
- test_recursive_with_red_termination_condition = skip
- test_compile_time_const_tuple = skip
test_residual_red_call = skip
- test_residual_red_call_with_exc = skip
-
- test_green_char_at_merge = skip #->SomeObject() (CharRepr @rgenop.py:141 ?)
+ test_merge_structures = skip
+ test_simple_meth = skip
+ test_simple_red_meth = skip
+ #failing...
+ if skip_failing:
+ test_compile_time_const_tuple = skip
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py Fri Jan 12 16:02:37 2007
@@ -1,12 +1,47 @@
import py
+from pypy.rlib.objectmodel import specialize
+from pypy.rpython.memory.lltypelayout import convert_offset_to_int
from pypy.jit.codegen.llvm.test.test_llvmjit import skip_unsupported_platform
from pypy.jit.codegen.i386.test.test_operation import BasicTests
from pypy.jit.codegen.llvm.rgenop import RLLVMGenOp
from pypy.jit.codegen.llvm.llvmjit import llvm_version, MINIMAL_VERSION
+def conv(n):
+ if not isinstance(n, int) and not isinstance(n, str):
+ n = convert_offset_to_int(n)
+ return n
+
+
+class RGenOpPacked(RLLVMGenOp):
+ """Like RLLVMGenOp, but produces concrete offsets in the tokens
+ instead of llmemory.offsets. These numbers may not agree with
+ your C compiler's.
+ """
+
+ @staticmethod
+ @specialize.memo()
+ def fieldToken(T, name):
+ return tuple(map(conv, RLLVMGenOp.fieldToken(T, name)))
+
+ @staticmethod
+ @specialize.memo()
+ def arrayToken(A):
+ return tuple(map(conv, RLLVMGenOp.arrayToken(A)))
+
+ @staticmethod
+ @specialize.memo()
+ def allocToken(T):
+ return conv(RLLVMGenOp.allocToken(T))
+
+ @staticmethod
+ @specialize.memo()
+ def varsizeAllocToken(A):
+ return tuple(map(conv, RLLVMGenOp.varsizeAllocToken(A)))
+
+
class LLVMTestBasicMixin(object):
- RGenOp = RLLVMGenOp
+ RGenOp = RGenOpPacked
class TestBasic(LLVMTestBasicMixin,
@@ -23,7 +58,7 @@
llvm_version(), MINIMAL_VERSION))
if llvm_version() < 2.0:
- test_float_arithmetic = skip_too_minimal #segfault
+ test_float_arithmetic = skip_too_minimal #40.0 + 2.0 = 2.0? (mmx issue?)
test_unsigned = skip_too_minimal #uint_invert uses incorrect xor constant?
test_float_cast = skip #works when f64 is 'float' but not when 'double' because of 0.0 compare
From cfbolz at codespeak.net Fri Jan 12 16:37:29 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 16:37:29 +0100 (CET)
Subject: [pypy-svn] r36587 - pypy/dist/pypy/rpython
Message-ID: <20070112153729.688DE1007D@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 16:37:03 2007
New Revision: 36587
Modified:
pypy/dist/pypy/rpython/extfunc.py
pypy/dist/pypy/rpython/rtyper.py
Log:
(arigo, cfbolz): don't always look at the graphs of all type systems
Modified: pypy/dist/pypy/rpython/extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunc.py (original)
+++ pypy/dist/pypy/rpython/extfunc.py Fri Jan 12 16:37:03 2007
@@ -11,17 +11,6 @@
for arg, expected in zip(args_s, self.signature_args):
arg = unionof(arg, expected)
assert expected.contains(arg)
-
- for type_system in ['lltype', 'ootype']:
- impl = getattr(self, type_system + 'impl', None)
- if impl:
- key = impl.im_func
- pbc = self.bookkeeper.immutablevalue(impl.im_func)
- s_result = self.bookkeeper.emulate_pbc_call(key, pbc,
- self.signature_args)
- s_result = unionof(s_result, self.signature_result)
- assert self.signature_result.contains(s_result)
-
return self.signature_result
def specialize_call(self, hop):
@@ -34,14 +23,11 @@
method_name = rtyper.type_system.name[:2] + 'typeimpl'
impl = getattr(self, method_name, None)
if impl:
- hop2 = hop.copy()
- v = Constant(impl.im_func)
- bookkeeper = rtyper.annotator.bookkeeper
- hop2.v_s_insertfirstarg(v, bookkeeper.immutablevalue(impl.im_func))
- return hop2.dispatch()
+ obj = rtyper.getannmixlevel().delayedfunction(
+ impl.im_func, self.signature_args, self.signature_result)
else:
obj = rtyper.type_system.getexternalcallable(args_ll, ll_result,
name, _entry=self, _callable=self.instance)
- vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
- hop.exception_is_here()
- return hop.genop('direct_call', vlist, r_result)
+ vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
+ hop.exception_is_here()
+ return hop.genop('direct_call', vlist, r_result)
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Fri Jan 12 16:37:03 2007
@@ -187,12 +187,20 @@
ldef = listdef.ListDef(None, annmodel.SomeString())
self.list_of_str_repr = self.getrepr(annmodel.SomeList(ldef))
+ def getannmixlevel(self):
+ if self.annmixlevel is not None:
+ return self.annmixlevel
+ from pypy.rpython.annlowlevel import MixLevelHelperAnnotator
+ self.annmixlevel = MixLevelHelperAnnotator(self)
+ return self.annmixlevel
+
def specialize_more_blocks(self):
if self.already_seen:
newtext = ' more'
else:
newtext = ''
blockcount = 0
+ self.annmixlevel = None
while True:
# look for blocks not specialized yet
pending = [block for block in self.annotator.annotated
@@ -234,6 +242,10 @@
raise TyperError("there were %d error" % len(self.typererrors))
self.log.event('-=- specialized %d%s blocks -=-' % (
blockcount, newtext))
+ annmixlevel = self.annmixlevel
+ del self.annmixlevel
+ if annmixlevel is not None:
+ annmixlevel.finish()
def dump_typererrors(self, num=None, minimize=True, to_log=False):
c = 0
From ericvrp at codespeak.net Fri Jan 12 16:49:04 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 12 Jan 2007 16:49:04 +0100 (CET)
Subject: [pypy-svn] r36588 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070112154904.657CE10083@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 12 16:49:00 2007
New Revision: 36588
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
Log:
some fixes to keep jit/codegen/llvm llvm 2.0 friendly
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Fri Jan 12 16:49:00 2007
@@ -567,8 +567,12 @@
if restype is gv_x.type:
return self.genop_same_as(None, gv_x)
gv_result = Var(restype)
+ if restype[-1] == '*':
+ t = bitcast
+ else:
+ t = zext
self.asm.append(' %s=%s %s to %s' % (
- gv_result.operand2(), zext, gv_x.operand(), restype))
+ gv_result.operand2(), t, gv_x.operand(), restype))
return gv_result
def _trunc_to(self, gv_x, restype=None):
@@ -877,7 +881,7 @@
self.asm.append(' %s=getelementptr %s,%s %s' % (
gv_p.operand2(), gv_result.operand(), i32, length_offset))
- gv_p2 = self._cast_to(gv_p, pi32) #warning: length field hardcoded here
+ gv_p2 = self._cast_to(gv_p, pi32) #warning: length field hardcoded as int here
self.asm.append(' store %s, %s' % (gv_size.operand(), gv_p2.operand()))
return gv_result
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_operation.py Fri Jan 12 16:49:00 2007
@@ -58,10 +58,11 @@
llvm_version(), MINIMAL_VERSION))
if llvm_version() < 2.0:
- test_float_arithmetic = skip_too_minimal #40.0 + 2.0 = 2.0? (mmx issue?)
test_unsigned = skip_too_minimal #uint_invert uses incorrect xor constant?
- test_float_cast = skip #works when f64 is 'float' but not when 'double' because of 0.0 compare
+ test_float_arithmetic = skip #XXX llvmjit.execute() returns an int :-(
+ test_float_cast = skip #XXX llvmjit.execute() returns an int :-(
+
test_float_pow = skip
test_unichar_array = skip
test_char_unichar_fields = skip
From fijal at codespeak.net Fri Jan 12 17:29:17 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 17:29:17 +0100 (CET)
Subject: [pypy-svn] r36590 - in pypy/dist/pypy/annotation: . test
Message-ID: <20070112162917.A3E101007D@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 17:29:15 2007
New Revision: 36590
Modified:
pypy/dist/pypy/annotation/binaryop.py
pypy/dist/pypy/annotation/test/test_annrpython.py
Log:
(arigo, fijal) Wack a bit union of PBC and GenericCallback
Modified: pypy/dist/pypy/annotation/binaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/binaryop.py (original)
+++ pypy/dist/pypy/annotation/binaryop.py Fri Jan 12 17:29:15 2007
@@ -685,9 +685,9 @@
class __extend__(pairtype(SomeGenericCallable, SomePBC)):
def union((gencall, pbc)):
- unique_key = "unionof(SomeGenericCallable, SomePBC)"
- if len(pbc.descriptions):
- bk = pbc.descriptions.iterkeys().next().bookkeeper
+ for desc in pbc.descriptions:
+ unique_key = desc
+ bk = desc.bookkeeper
s_result = bk.emulate_pbc_call(unique_key, pbc, gencall.args_s)
s_result = unionof(s_result, gencall.s_result)
assert gencall.s_result.contains(s_result)
Modified: pypy/dist/pypy/annotation/test/test_annrpython.py
==============================================================================
--- pypy/dist/pypy/annotation/test/test_annrpython.py (original)
+++ pypy/dist/pypy/annotation/test/test_annrpython.py Fri Jan 12 17:29:15 2007
@@ -2465,6 +2465,7 @@
a = h
else:
a = c
+ x = x + .01
return a(x)
#def fun(x):
From arigo at codespeak.net Fri Jan 12 17:29:20 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Fri, 12 Jan 2007 17:29:20 +0100 (CET)
Subject: [pypy-svn] r36591 - pypy/branch/i386-regalloc/pypy/jit/codegen/test
Message-ID: <20070112162920.7E11A10082@code0.codespeak.net>
Author: arigo
Date: Fri Jan 12 17:29:16 2007
New Revision: 36591
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
A larger test, using 150 variables at once.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Fri Jan 12 17:29:16 2007
@@ -1,3 +1,4 @@
+import random
from pypy.rpython.annlowlevel import MixLevelAnnotatorPolicy
from pypy.rlib.objectmodel import keepalive_until_here
from pypy.rpython.lltypesystem import lltype
@@ -59,6 +60,62 @@
return res
return dummy_runner
+FUNC100 = lltype.FuncType([lltype.Signed]*100, lltype.Signed)
+
+def largedummy_example():
+ args = [random.randrange(-10, 50) for i in range(100)]
+ total = 0
+ for i in range(0, 100, 2):
+ total += args[i] - args[i+1]
+ return args, total
+
+def make_largedummy(rgenop):
+ # 'return v0-v1+v2-v3+v4-v5...+v98-v99'
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC100)
+ builder, gv_largedummyfn, gvs = rgenop.newgraph(sigtoken, "largedummy")
+
+ for i in range(0, 100, 2):
+ gvs.append(builder.genop2("int_sub", gvs[i], gvs[i+1]))
+
+ builder.enter_next_block([signed_kind] * 150, gvs)
+ while len(gvs) > 101:
+ gv_sum = builder.genop2("int_add", gvs.pop(), gvs.pop())
+ gvs.append(gv_sum)
+
+ builder.finish_and_return(sigtoken, gvs.pop())
+
+ builder.end()
+ return gv_largedummyfn
+
+def get_largedummy_runner(RGenOp):
+ def largedummy_runner(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9,
+ v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+ v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+ v40, v41, v42, v43, v44, v45, v46, v47, v48, v49,
+ v50, v51, v52, v53, v54, v55, v56, v57, v58, v59,
+ v60, v61, v62, v63, v64, v65, v66, v67, v68, v69,
+ v70, v71, v72, v73, v74, v75, v76, v77, v78, v79,
+ v80, v81, v82, v83, v84, v85, v86, v87, v88, v89,
+ v90, v91, v92, v93, v94, v95, v96, v97, v98, v99):
+ rgenop = RGenOp()
+ gv_largedummyfn = make_largedummy(rgenop)
+ largedummyfn = gv_largedummyfn.revealconst(lltype.Ptr(FUNC100))
+ res = largedummyfn(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9,
+ v10, v11, v12, v13, v14, v15, v16, v17, v18, v19,
+ v20, v21, v22, v23, v24, v25, v26, v27, v28, v29,
+ v30, v31, v32, v33, v34, v35, v36, v37, v38, v39,
+ v40, v41, v42, v43, v44, v45, v46, v47, v48, v49,
+ v50, v51, v52, v53, v54, v55, v56, v57, v58, v59,
+ v60, v61, v62, v63, v64, v65, v66, v67, v68, v69,
+ v70, v71, v72, v73, v74, v75, v76, v77, v78, v79,
+ v80, v81, v82, v83, v84, v85, v86, v87, v88, v89,
+ v90, v91, v92, v93, v94, v95, v96, v97, v98, v99)
+ keepalive_until_here(rgenop) # to keep the code blocks alive
+ return res
+ return largedummy_runner
+
def make_branching(rgenop):
# 'if x > 5: return x-1
# else: return y'
@@ -409,6 +466,20 @@
res = fn(2)
assert res == 8222
+ def test_largedummy_direct(self):
+ rgenop = self.RGenOp()
+ gv_largedummyfn = make_largedummy(rgenop)
+ fnptr = self.cast(gv_largedummyfn, 100)
+ args, expected = largedummy_example()
+ res = fnptr(*args)
+ assert res == expected
+
+ def test_largedummy_compile(self):
+ fn = self.compile(get_largedummy_runner(self.RGenOp), [int, int])
+ args, expected = largedummy_example()
+ res = fn(*args)
+ assert res == expected
+
def test_branching_direct(self):
rgenop = self.RGenOp()
gv_branchingfn = make_branching(rgenop)
From fijal at codespeak.net Fri Jan 12 17:30:42 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 17:30:42 +0100 (CET)
Subject: [pypy-svn] r36592 - in pypy/dist/pypy/rpython: . lltypesystem test
Message-ID: <20070112163042.75ADE10072@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 17:30:38 2007
New Revision: 36592
Added:
pypy/dist/pypy/rpython/lltypesystem/rgeneric.py
pypy/dist/pypy/rpython/rgeneric.py
pypy/dist/pypy/rpython/test/test_rgeneric.py
Modified:
pypy/dist/pypy/rpython/rtyper.py
pypy/dist/pypy/rpython/typesystem.py
Log:
(arigo, fijal) - Add rgeneric repr, so now we can provide a callback to an external function.
Added: pypy/dist/pypy/rpython/lltypesystem/rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/lltypesystem/rgeneric.py Fri Jan 12 17:30:38 2007
@@ -0,0 +1,9 @@
+
+from pypy.rpython.rgeneric import AbstractGenericCallableRepr
+from pypy.rpython.lltypesystem.lltype import Ptr, FuncType
+
+class GenericCallableRepr(AbstractGenericCallableRepr):
+ def create_low_leveltype(self):
+ l_args = [r_arg.lowleveltype for r_arg in self.args_r]
+ l_retval = self.r_result.lowleveltype
+ return Ptr(FuncType(l_args, l_retval))
Added: pypy/dist/pypy/rpython/rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/rgeneric.py Fri Jan 12 17:30:38 2007
@@ -0,0 +1,46 @@
+from pypy.annotation import model as annmodel
+from pypy.rpython.rmodel import Repr
+from pypy.rpython.rpbc import AbstractFunctionsPBCRepr
+from pypy.annotation.pairtype import pairtype
+from pypy.rpython.lltypesystem import lltype
+
+class AbstractGenericCallableRepr(Repr):
+ def __init__(self, rtyper, s_generic):
+ self.rtyper = rtyper
+ self.s_generic = s_generic
+ self.args_r = [self.rtyper.getrepr(arg) for arg in s_generic.args_s]
+ self.r_result = self.rtyper.getrepr(s_generic.s_result)
+ self.lowleveltype = self.create_low_leveltype()
+
+ def rtype_simple_call(self, hop):
+ return self.call('simple_call', hop)
+
+ def rtype_call_args(self, hop):
+ return self.call('call_args', hop)
+
+ def call(self, opname, hop):
+ bk = self.rtyper.annotator.bookkeeper
+ vlist = hop.inputargs(self, *self.args_r) + [hop.inputconst(lltype.Void, None)]
+ hop.exception_is_here()
+ v_result = hop.genop('indirect_call', vlist, resulttype=self.r_result)
+ return v_result
+
+ def convert_const(self, value):
+ bookkeeper = self.rtyper.annotator.bookkeeper
+ if value is None:
+ return self.rtyper.type_system.null_callable(self.lowleveltype)
+ r_func = self.rtyper.getrepr(bookkeeper.immutablevalue(value))
+ return r_func.get_unique_llfn().value
+
+class __extend__(annmodel.SomeGenericCallable):
+ def rtyper_makerepr(self, rtyper):
+ return rtyper.type_system.rgeneric.GenericCallableRepr(rtyper, self)
+
+class __extend__(pairtype(AbstractFunctionsPBCRepr, AbstractGenericCallableRepr)):
+ def convert_from_to((pbcrepr, gencallrepr), v, llops):
+ if pbcrepr.lowleveltype is lltype.Void:
+ return gencallrepr.convert_const(pbcrepr.s_pbc.const)
+ if pbcrepr.lowleveltype == gencallrepr.lowleveltype:
+ return v
+ return NotImplemented
+
Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py (original)
+++ pypy/dist/pypy/rpython/rtyper.py Fri Jan 12 17:30:38 2007
@@ -932,5 +932,6 @@
from pypy.rpython import rclass, rbuiltin, rpbc, rspecialcase
from pypy.rpython import rexternalobj
from pypy.rpython import rptr
+from pypy.rpython import rgeneric
from pypy.rpython import raddress # memory addresses
from pypy.rpython.ootypesystem import rootype
Added: pypy/dist/pypy/rpython/test/test_rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/test/test_rgeneric.py Fri Jan 12 17:30:38 2007
@@ -0,0 +1,40 @@
+from pypy.rpython.rtyper import RPythonTyper
+from pypy.annotation import model as annmodel
+from pypy.annotation.annrpython import RPythonAnnotator
+from pypy.annotation import policy
+from pypy.rpython.test.test_llinterp import interpret, interpret_raises
+
+import py
+
+class TestRGeneric:
+ def test_some_generic_function_call(self):
+ def h(x):
+ return int(x)
+
+ def c(x):
+ return int(x) + 1
+
+ def default(x):
+ return int(x) + 3
+
+ def g(a, x):
+ if x == -1:
+ a = None
+ if x > 0:
+ if x == 1:
+ a = h
+ else:
+ a = c
+ x = x + 0.01
+ return a(x)
+
+ def f(x):
+ return g(default, x)
+
+ g._annenforceargs_ = policy.Sig(annmodel.SomeGenericCallable(
+ args=[annmodel.SomeFloat()], result=annmodel.SomeInteger()),
+ float)
+
+ assert interpret(f, [1.]) == 1
+ assert interpret(f, [10.]) == 11
+ assert interpret(f, [-3.]) == 0
Modified: pypy/dist/pypy/rpython/typesystem.py
==============================================================================
--- pypy/dist/pypy/rpython/typesystem.py (original)
+++ pypy/dist/pypy/rpython/typesystem.py Fri Jan 12 17:30:38 2007
@@ -21,7 +21,7 @@
except ImportError:
return None
if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist',
- 'rslice', 'rdict', 'rrange', 'rstr',
+ 'rslice', 'rdict', 'rrange', 'rstr', 'rgeneric',
'll_str', 'exceptiondata'):
mod = load(name)
if mod is not None:
From arigo at codespeak.net Fri Jan 12 17:33:11 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Fri, 12 Jan 2007 17:33:11 +0100 (CET)
Subject: [pypy-svn] r36593 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070112163311.44DBA10080@code0.codespeak.net>
Author: arigo
Date: Fri Jan 12 17:33:10 2007
New Revision: 36593
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
Log:
Started support for labels. Don't force code generation at each enter_next_block().
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Fri Jan 12 17:33:10 2007
@@ -14,6 +14,8 @@
RK_WORD = 1
RK_CC = 2
+DEBUG_TRAP = conftest.option.trap
+
class Operation(GenVar):
clobbers_cc = True
@@ -46,14 +48,14 @@
dstop = allocator.get_operand(self)
except KeyError:
return # result not used
- srcop = self.get_operand(self.x)
+ srcop = allocator.get_operand(self.x)
if srcop != dstop:
+ mc = allocator.mc
try:
- self.mc.MOV(dstop, srcop)
+ mc.MOV(dstop, srcop)
except FailedToImplement:
- self.mc.MOV(ecx, srcop)
- self.mc.MOV(dstop, ecx)
- return dstop
+ mc.MOV(ecx, srcop)
+ mc.MOV(dstop, ecx)
class OpCompare1(Op1):
result_kind = RK_CC
@@ -117,23 +119,44 @@
opname = 'int_gt'
cc_result = Conditions['G']
-class JumpIfFalse(Operation):
+class JumpIf(Operation):
clobbers_cc = False
result_kind = RK_NO_RESULT
- def __init__(self, gv_condition, targetbuilder):
+ def __init__(self, gv_condition, targetbuilder, negate):
assert 0 <= gv_condition.cc_result < INSN_JMP
self.gv_condition = gv_condition
self.targetbuilder = targetbuilder
+ self.negate = negate
def allocate(self, allocator):
allocator.using_cc(self.gv_condition)
def generate(self, allocator):
- cc = cond_negate(self.gv_condition.cc_result)
+ cc = self.gv_condition.cc_result
+ if self.negate:
+ cc = cond_negate(cc)
mc = allocator.mc
targetbuilder = self.targetbuilder
targetbuilder.set_coming_from(mc, insncond=cc)
targetbuilder.inputoperands = [allocator.get_operand(gv)
for gv in targetbuilder.inputargs_gv]
+class OpLabel(Operation):
+ clobbers_cc = False
+ result_kind = RK_NO_RESULT
+ def __init__(self, lbl, args_gv):
+ self.lbl = lbl
+ self.args_gv = args_gv
+ def allocate(self, allocator):
+ for v in self.args_gv:
+ allocator.using(v)
+ def generate(self, allocator):
+ lbl = self.lbl
+ lbl.targetaddr = allocator.mc.tell()
+ lbl.inputoperands = [allocator.get_operand(v) for v in self.args_gv]
+
+class Label(GenLabel):
+ targetaddr = 0
+ inputoperands = None
+
# ____________________________________________________________
class IntConst(GenConst):
@@ -449,11 +472,20 @@
return mc
def enter_next_block(self, kinds, args_gv):
- mc = self.generate_block_code(args_gv)
- args_gv[:] = self.inputargs_gv
- self.set_coming_from(mc)
- self.rgenop.close_mc(mc)
- self.start_writing()
+## mc = self.generate_block_code(args_gv)
+## assert len(self.inputargs_gv) == len(args_gv)
+## args_gv[:len(args_gv)] = self.inputargs_gv
+## self.set_coming_from(mc)
+## self.rgenop.close_mc(mc)
+## self.start_writing()
+ for i in range(len(args_gv)):
+ op = OpSameAs(args_gv[i])
+ args_gv[i] = op
+ self.operations.append(op)
+ lbl = Label()
+ lblop = OpLabel(lbl, args_gv)
+ self.operations.append(lblop)
+ return lbl
def set_coming_from(self, mc, insncond=INSN_JMP):
self.coming_from_cond = insncond
@@ -480,7 +512,15 @@
if gv_condition.cc_result < 0:
gv_condition = OpIntIsTrue(gv_condition)
self.operations.append(gv_condition)
- self.operations.append(JumpIfFalse(gv_condition, newbuilder))
+ self.operations.append(JumpIf(gv_condition, newbuilder, negate=True))
+ return newbuilder
+
+ def jump_if_true(self, gv_condition, args_for_jump_gv):
+ newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None)
+ if gv_condition.cc_result < 0:
+ gv_condition = OpIntIsTrue(gv_condition)
+ self.operations.append(gv_condition)
+ self.operations.append(JumpIf(gv_condition, newbuilder, negate=False))
return newbuilder
def finish_and_return(self, sigtoken, gv_returnvar):
@@ -548,7 +588,7 @@
# --- prologue ---
mc = self.open_mc()
entrypoint = mc.tell()
- if conftest.option.trap:
+ if DEBUG_TRAP:
mc.BREAKPOINT()
mc.PUSH(ebp)
mc.MOV(ebp, esp)
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py Fri Jan 12 17:33:10 2007
@@ -251,6 +251,7 @@
assert len(s) in (1, 2, 4)
result = 0
shift = 0
+ char = '\x00' # flow space workaround
for char in s:
result |= ord(char) << shift
shift += 8
From fijal at codespeak.net Fri Jan 12 17:46:32 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 17:46:32 +0100 (CET)
Subject: [pypy-svn] r36594 - in pypy/dist/pypy/rpython: ootypesystem test
Message-ID: <20070112164632.AA60610074@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 17:46:31 2007
New Revision: 36594
Added:
pypy/dist/pypy/rpython/ootypesystem/rgeneric.py
Modified:
pypy/dist/pypy/rpython/test/test_rgeneric.py
Log:
Support for ootypesystem
Added: pypy/dist/pypy/rpython/ootypesystem/rgeneric.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/ootypesystem/rgeneric.py Fri Jan 12 17:46:31 2007
@@ -0,0 +1,9 @@
+
+from pypy.rpython.rgeneric import AbstractGenericCallableRepr
+from pypy.rpython.ootypesystem import ootype
+
+class GenericCallableRepr(AbstractGenericCallableRepr):
+ def create_low_leveltype(self):
+ l_args = [r_arg.lowleveltype for r_arg in self.args_r]
+ l_retval = self.r_result.lowleveltype
+ return ootype.StaticMethod(l_args, l_retval)
Modified: pypy/dist/pypy/rpython/test/test_rgeneric.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rgeneric.py (original)
+++ pypy/dist/pypy/rpython/test/test_rgeneric.py Fri Jan 12 17:46:31 2007
@@ -5,8 +5,9 @@
from pypy.rpython.test.test_llinterp import interpret, interpret_raises
import py
+from pypy.rpython.test.tool import LLRtypeMixin, OORtypeMixin
-class TestRGeneric:
+class BaseRGenericTest:
def test_some_generic_function_call(self):
def h(x):
return int(x)
@@ -38,3 +39,9 @@
assert interpret(f, [1.]) == 1
assert interpret(f, [10.]) == 11
assert interpret(f, [-3.]) == 0
+
+class TestLLRgeneric(BaseRGenericTest, LLRtypeMixin):
+ pass
+
+class TestOORgeneric(BaseRGenericTest, OORtypeMixin):
+ pass
From mwh at codespeak.net Fri Jan 12 17:54:48 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Fri, 12 Jan 2007 17:54:48 +0100 (CET)
Subject: [pypy-svn] r36595 - in pypy/dist/pypy/jit/codegen: ppc ppc/test test
Message-ID: <20070112165448.022C410083@code0.codespeak.net>
Author: mwh
Date: Fri Jan 12 17:54:47 2007
New Revision: 36595
Modified:
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
(niko, mwh)
So cmp2info_flipped was mostly wrong. Fix that, and another bug that only
caused doing some work over and over again, and add a skipped test to do with
passing variables in the condition register across basic blocks which fails.
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Fri Jan 12 17:54:47 2007
@@ -257,6 +257,7 @@
self.arg_reg = allocator.loc_of(self.reg_args[0])
def emit(self, asm):
+ #print "CMPWI", asm.mc.tell()
asm.cmpwi(self.result_reg.number, self.arg_reg.number, self.imm.value)
class CMPWLI(CMPW):
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Jan 12 17:54:47 2007
@@ -454,12 +454,16 @@
if self.final_jump_addr != 0:
mc = self.rgenop.open_mc()
target = mc.tell()
- self.asm.mc = self.rgenop.ExistingCodeBlock(self.final_jump_addr, self.final_jump_addr+8)
+ self.asm.mc = self.rgenop.ExistingCodeBlock(
+ self.final_jump_addr, self.final_jump_addr+8)
self.asm.load_word(rSCRATCH, target)
self.asm.mc = mc
+ self.final_jump_addr = 0
+ self.closed = False
return self
else:
self._open()
+ self.closed = False
self.maybe_patch_start_here()
return self
@@ -475,6 +479,7 @@
self.initial_var2loc = self.allocate_and_emit(args_gv).var2loc
self.insns = []
self.final_jump_addr = self.asm.mc.tell()
+ self.closed = True
self.asm.nop()
self.asm.nop()
self.asm.mtctr(rSCRATCH)
@@ -666,10 +671,10 @@
cmp2info_flipped = {
# bit-in-crf negated
- 'gt': ( 1, 1 ),
- 'lt': ( 0, 1 ),
- 'le': ( 1, 0 ),
- 'ge': ( 0, 0 ),
+ 'gt': ( 0, 0 ),
+ 'lt': ( 1, 0 ),
+ 'le': ( 0, 1 ),
+ 'ge': ( 1, 1 ),
'eq': ( 2, 0 ),
'ne': ( 2, 1 ),
}
Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Fri Jan 12 17:54:47 2007
@@ -1,7 +1,7 @@
import py
from pypy.jit.codegen.ppc.rgenop import RPPCGenOp
from pypy.rpython.lltypesystem import lltype
-from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests, FUNC2
+from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests, FUNC, FUNC2
from ctypes import cast, c_int, c_void_p, CFUNCTYPE
from pypy.jit.codegen.ppc import instruction as insn
@@ -58,6 +58,53 @@
res = fnptr(2, 1)
assert res == 100101
+ def test_flipped_cmpwi(self):
+ # return
+ # 1>x + 10*(1=x) + 1000*(1<=x) + 10000*(1==x) + 100000*(1!=x)
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "multicmp")
+ gv_one = rgenop.genconst(1)
+
+ gv_gt = builder.genop2("int_gt", gv_one, gv_x)
+ gv_lt = builder.genop2("int_lt", gv_one, gv_x)
+ gv_ge = builder.genop2("int_ge", gv_one, gv_x)
+ gv_le = builder.genop2("int_le", gv_one, gv_x)
+ gv_eq = builder.genop2("int_eq", gv_one, gv_x)
+ gv_ne = builder.genop2("int_ne", gv_one, gv_x)
+
+ gv_gt2 = gv_gt
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+
+ gv_r0 = gv_gt
+ gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
+ gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
+ gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
+ gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
+ gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
+
+ builder.finish_and_return(sigtoken, gv_r5)
+ builder.end()
+ fnptr = cast(c_void_p(gv_callable.value), CFUNCTYPE(c_int))
+
+ res = fnptr(0)
+ assert res == 100101
+
+ res = fnptr(1)
+ assert res == 11100
+
+ res = fnptr(2)
+ assert res == 101010
+
+ def test_longwinded_and_direct(self):
+ py.test.skip("failing right now")
+
class TestRPPCGenopNoRegs(TestRPPCGenop):
RGenOp = FewRegisters
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Fri Jan 12 17:54:47 2007
@@ -366,7 +366,44 @@
keepalive_until_here(rgenop) # to keep the code blocks alive
return res
return runner
-
+
+def make_longwinded_and(rgenop):
+ # def f(y): return 2 <= y <= 4
+ # but more like this:
+ # def f(y)
+ # x = 2 <= y
+ # if x:
+ # x = y <= 4
+ # if x:
+ # return 1
+ # else:
+ # return 0
+
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "abs")
+
+ gv_x = builder.genop2("int_le", rgenop.genconst(2), gv_y)
+
+ false_builder = builder.jump_if_false(gv_x, [gv_x])
+
+ gv_x2 = builder.genop2("int_le", gv_y, rgenop.genconst(4))
+
+ args_gv = [gv_x2]
+ label = builder.enter_next_block([signed_kind], args_gv)
+ [gv_x2] = args_gv
+
+ return_false_builder = builder.jump_if_false(gv_x2, [])
+
+ builder.finish_and_return(sigtoken, rgenop.genconst(1))
+
+ false_builder.start_writing()
+ false_builder.finish_and_goto([gv_x], label)
+
+ return_false_builder.start_writing()
+ return_false_builder.finish_and_return(sigtoken, rgenop.genconst(0))
+
+ return gv_f
class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
RGenOp = None
@@ -566,3 +603,23 @@
assert res == 2
res = fn(-72)
assert res == 72
+
+ def test_longwinded_and_direct(self):
+ rgenop = self.RGenOp()
+ gv_fn = make_longwinded_and(rgenop)
+ fnptr = self.cast(gv_fn, 1)
+
+ res = fnptr(1)
+ assert res == 0
+
+ res = fnptr(2)
+ assert res == 1
+
+ res = fnptr(3)
+ assert res == 1
+
+ res = fnptr(4)
+ assert res == 1
+
+ res = fnptr(5)
+ assert res == 0
From ericvrp at codespeak.net Fri Jan 12 17:57:44 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 12 Jan 2007 17:57:44 +0100 (CET)
Subject: [pypy-svn] r36596 - pypy/dist/pypy/jit/codegen/llvm/test
Message-ID: <20070112165744.CAD5710086@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 12 17:57:43 2007
New Revision: 36596
Modified:
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
Log:
mark tests that fail on llvm 2.0
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Fri Jan 12 17:57:43 2007
@@ -31,6 +31,13 @@
test_two_loops_merging = skip_too_minimal #segfault
test_green_char_at_merge = skip #segfault
test_residual_red_call_with_exc = skip
+ else: #needs fixing for >= 2.0
+ test_red_array = skip
+ test_red_struct_array = skip
+ test_red_varsized_struct = skip
+ test_array_of_voids = skip
+ test_merge_structures = skip
+ test_green_char_at_merge = skip
if skip_passing:
test_very_simple = skip
From fijal at codespeak.net Fri Jan 12 18:04:27 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 18:04:27 +0100 (CET)
Subject: [pypy-svn] r36597 - pypy/dist/pypy/annotation
Message-ID: <20070112170427.D39E51007C@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 18:04:19 2007
New Revision: 36597
Added:
pypy/dist/pypy/annotation/signature.py
Modified:
pypy/dist/pypy/annotation/policy.py
Log:
(fijal, pedronis, arigo) Move signature to a different file to decrease the confusion
Modified: pypy/dist/pypy/annotation/policy.py
==============================================================================
--- pypy/dist/pypy/annotation/policy.py (original)
+++ pypy/dist/pypy/annotation/policy.py Fri Jan 12 18:04:19 2007
@@ -6,6 +6,7 @@
# or we create a cycle.
from pypy.annotation import model as annmodel
from pypy.annotation.bookkeeper import getbookkeeper
+from pypy.annotation.signature import Sig
import types
@@ -92,42 +93,3 @@
bk = getbookkeeper()
return bk.immutablevalue(None)
-# ____________________________________________________________
-
-class Sig(object):
-
- def __init__(self, *argtypes):
- self.argtypes = argtypes
-
- def __call__(self, funcdesc, inputcells):
- from pypy.rpython.lltypesystem import lltype
- args_s = []
- for i, argtype in enumerate(self.argtypes):
- if isinstance(argtype, (types.FunctionType, types.MethodType)):
- argtype = argtype(*inputcells)
- if isinstance(argtype, annmodel.SomeObject):
- args_s.append(argtype)
- elif isinstance(argtype, lltype.LowLevelType):
- if argtype is lltype.Void:
- # XXX the mapping between Void and annotation
- # is not quite well defined
- s_input = inputcells[i]
- assert isinstance(s_input, annmodel.SomePBC)
- assert s_input.is_constant()
- args_s.append(s_input)
- else:
- args_s.append(annmodel.lltype_to_annotation(argtype))
- else:
- args_s.append(funcdesc.bookkeeper.valueoftype(argtype))
- if len(inputcells) != len(args_s):
- raise Exception("%r: expected %d args, got %d" % (funcdesc,
- len(args_s),
- len(inputcells)))
- for i, (s_arg, s_input) in enumerate(zip(args_s, inputcells)):
- if not s_arg.contains(s_input):
- raise Exception("%r argument %d:\n"
- "expected %s,\n"
- " got %s" % (funcdesc, i+1,
- s_arg,
- s_input))
- inputcells[:] = args_s
Added: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/annotation/signature.py Fri Jan 12 18:04:19 2007
@@ -0,0 +1,41 @@
+
+import types
+from pypy.annotation import model as annmodel
+
+class Sig(object):
+
+ def __init__(self, *argtypes):
+ self.argtypes = argtypes
+
+ def __call__(self, funcdesc, inputcells):
+ from pypy.rpython.lltypesystem import lltype
+ args_s = []
+ for i, argtype in enumerate(self.argtypes):
+ if isinstance(argtype, (types.FunctionType, types.MethodType)):
+ argtype = argtype(*inputcells)
+ if isinstance(argtype, annmodel.SomeObject):
+ args_s.append(argtype)
+ elif isinstance(argtype, lltype.LowLevelType):
+ if argtype is lltype.Void:
+ # XXX the mapping between Void and annotation
+ # is not quite well defined
+ s_input = inputcells[i]
+ assert isinstance(s_input, annmodel.SomePBC)
+ assert s_input.is_constant()
+ args_s.append(s_input)
+ else:
+ args_s.append(annmodel.lltype_to_annotation(argtype))
+ else:
+ args_s.append(funcdesc.bookkeeper.valueoftype(argtype))
+ if len(inputcells) != len(args_s):
+ raise Exception("%r: expected %d args, got %d" % (funcdesc,
+ len(args_s),
+ len(inputcells)))
+ for i, (s_arg, s_input) in enumerate(zip(args_s, inputcells)):
+ if not s_arg.contains(s_input):
+ raise Exception("%r argument %d:\n"
+ "expected %s,\n"
+ " got %s" % (funcdesc, i+1,
+ s_arg,
+ s_input))
+ inputcells[:] = args_s
From fijal at codespeak.net Fri Jan 12 18:13:28 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 18:13:28 +0100 (CET)
Subject: [pypy-svn] r36598 - pypy/dist/pypy/annotation
Message-ID: <20070112171328.A48391007C@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 18:13:13 2007
New Revision: 36598
Modified:
pypy/dist/pypy/annotation/bookkeeper.py
pypy/dist/pypy/annotation/signature.py
Log:
(arigo, fijal) - Create new function annotationoftype, so we can create annotations out of type in a more general way.
Modified: pypy/dist/pypy/annotation/bookkeeper.py
==============================================================================
--- pypy/dist/pypy/annotation/bookkeeper.py (original)
+++ pypy/dist/pypy/annotation/bookkeeper.py Fri Jan 12 18:13:13 2007
@@ -16,6 +16,7 @@
from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
from pypy.annotation import description
+from pypy.annotation.signature import annotationoftype
from pypy.interpreter.argument import Arguments, ArgErr
from pypy.rlib.rarithmetic import r_int, r_uint, r_ulonglong, r_longlong
from pypy.rlib.rarithmetic import base_int
@@ -539,39 +540,7 @@
clsdef.add_source_for_attribute(attr, source) # can trigger reflowing
def valueoftype(self, t):
- """The most precise SomeValue instance that contains all
- objects of type t."""
- assert isinstance(t, (type, types.ClassType))
- if t is bool:
- return SomeBool()
- elif t is int:
- return SomeInteger()
- elif issubclass(t, str): # py.lib uses annotated str subclasses
- return SomeString()
- elif t is float:
- return SomeFloat()
- elif t is list:
- return SomeList(MOST_GENERAL_LISTDEF)
- elif t is dict:
- return SomeDict(MOST_GENERAL_DICTDEF)
- # can't do tuple
- elif t is types.NoneType:
- return s_None
- elif t in EXTERNAL_TYPE_ANALYZERS:
- return SomeExternalObject(t)
-## elif hasattr(t, "compute_annotation"):
-## return t.compute_annotation()
- elif extregistry.is_registered_type(t, self.policy):
- entry = extregistry.lookup_type(t, self.policy)
- return entry.compute_annotation_bk(self)
- elif t.__module__ != '__builtin__' and t not in self.pbctypes:
- classdef = self.getuniqueclassdef(t)
- return SomeInstance(classdef)
- else:
- o = SomeObject()
- if t != object:
- o.knowntype = t
- return o
+ return annotationoftype(t, self)
def get_classpbc_attr_families(self, attrname):
"""Return the UnionFind for the ClassAttrFamilies corresponding to
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Fri Jan 12 18:13:13 2007
@@ -1,6 +1,48 @@
import types
-from pypy.annotation import model as annmodel
+from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\
+ SomeFloat, SomeList, SomeDict, s_None, SomeExternalObject,\
+ SomeObject, SomeInstance
+from pypy.annotation.classdef import ClassDef, InstanceSource
+from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
+from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
+
+def annotationoftype(t, bookkeeper=False):
+ from pypy.annotation.builtin import BUILTIN_ANALYZERS
+ from pypy.annotation.builtin import EXTERNAL_TYPE_ANALYZERS
+ from pypy.rpython import extregistry
+
+ """The most precise SomeValue instance that contains all
+ objects of type t."""
+ assert isinstance(t, (type, types.ClassType))
+ if t is bool:
+ return SomeBool()
+ elif t is int:
+ return SomeInteger()
+ elif issubclass(t, str): # py.lib uses annotated str subclasses
+ return SomeString()
+ elif t is float:
+ return SomeFloat()
+ elif t is list:
+ return SomeList(MOST_GENERAL_LISTDEF)
+ elif t is dict:
+ return SomeDict(MOST_GENERAL_DICTDEF)
+ # can't do tuple
+ elif t is types.NoneType:
+ return s_None
+ elif t in EXTERNAL_TYPE_ANALYZERS:
+ return SomeExternalObject(t)
+ elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy):
+ entry = extregistry.lookup_type(t, bookkeeper.policy)
+ return entry.compute_annotation_bk(bookkeeper)
+ elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes:
+ classdef = bookkeeper.getuniqueclassdef(t)
+ return SomeInstance(classdef)
+ else:
+ o = SomeObject()
+ if t != object:
+ o.knowntype = t
+ return o
class Sig(object):
@@ -10,6 +52,7 @@
def __call__(self, funcdesc, inputcells):
from pypy.rpython.lltypesystem import lltype
args_s = []
+ from pypy.annotation import model as annmodel
for i, argtype in enumerate(self.argtypes):
if isinstance(argtype, (types.FunctionType, types.MethodType)):
argtype = argtype(*inputcells)
From santagada at codespeak.net Fri Jan 12 18:14:17 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Fri, 12 Jan 2007 18:14:17 +0100 (CET)
Subject: [pypy-svn] r36599 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070112171417.E743710088@code0.codespeak.net>
Author: santagada
Date: Fri Jan 12 18:13:42 2007
New Revision: 36599
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
implemented typeof
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Fri Jan 12 18:13:42 2007
@@ -109,9 +109,7 @@
self.AssignmentExp = AssignmentExp
def eval(self, ctx):
- #print "Assign LHS = ", self.LHSExp
v1 = self.LHSExp.eval(ctx)
- #print "Assign Exp = ", self.AssignmentExp
v3 = self.AssignmentExp.eval(ctx).GetValue()
v1.PutValue(v3, ctx)
return v3
@@ -159,7 +157,6 @@
return w_Null
else:
w_obj = ctx.resolve_identifier(name).GetValue()
- #print "arglist = ", self.arglist
retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.get_args(ctx)])
return retval
@@ -226,7 +223,6 @@
def execute(self, ctx):
temp = self.condition.eval(ctx)
- #print "if condition = ", temp
if temp.ToBoolean():
return self.thenPart.execute(ctx)
else:
@@ -247,7 +243,6 @@
# TODO complete the funcion with strings comparison
s1 = x.ToPrimitive(ctx, 'Number')
s2 = y.ToPrimitive(ctx, 'Number')
- #print "ARC x = %s, y = %s"%(str(s1),str(s2))
if not (isinstance(s1, W_String) and isinstance(s2, W_String)):
s4 = s1.ToNumber()
s5 = s2.ToNumber()
@@ -313,7 +308,10 @@
Implements the Abstract Equality Comparison x == y
not following the specs yet
"""
- r = x.ToNumber() == y.ToNumber()
+ if isinstance(x, W_String) and isinstance(y, W_String):
+ r = x.ToString() == y.ToString()
+ else:
+ r = x.ToNumber() == y.ToNumber()
return r
class Eq(BinaryComparisonOp):
@@ -361,7 +359,6 @@
self.nodes = nodes
def get_args(self, ctx):
- #print "nodes = ", self.nodes
return [node.eval(ctx) for node in self.nodes]
class Minus(BinaryComparisonOp):
@@ -504,6 +501,13 @@
return tryresult
+class Typeof(Expression):
+ def __init__(self, op):
+ self.op = op
+
+ def eval(self, ctx):
+ return W_String(self.op.eval(ctx).GetValue().type())
+
class Undefined(Statement):
def execute(self, ctx):
return None
@@ -513,9 +517,7 @@
self.nodes = nodes
def execute(self, ctx):
- #print self.nodes
for var in self.nodes:
- #print var.name
var.execute(ctx)
class While(Statement):
@@ -683,7 +685,6 @@
node = Return(from_tree(gettreeitem(t, 'value')))
elif tp == 'SCRIPT':
f = gettreeitem(t, 'funDecls')
- # print f.symbol
if f.symbol == "dict":
func_decl = [from_tree(f),]
elif f.symbol == "list":
@@ -692,7 +693,6 @@
func_decl = []
v = gettreeitem(t, 'varDecls')
- # print v.symbol
if v.symbol == "dict":
var_decl = [from_tree(v),]
elif v.symbol == "list":
@@ -725,6 +725,8 @@
catchblock = from_tree(gettreeitem(catch, 'block'))
catchparam = gettreeitem(catch, 'varName').additional_info
node = Try(from_tree(gettreeitem(t, 'tryBlock')), catchblock, finallyblock, catchparam)
+ elif tp == 'TYPEOF':
+ node = Typeof(from_tree(gettreeitem(t, '0')))
elif tp == 'VAR':
node = Vars(getlist(t))
elif tp == 'WHILE':
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Fri Jan 12 18:13:42 2007
@@ -76,6 +76,9 @@
def __repr__(self):
return "<%s(%s)>" % (self.__class__.__name__, self.ToString())
+
+ def type(self):
+ return NotImplementedError
class W_Primitive(W_Root):
"""unifying parent for primitives"""
@@ -155,6 +158,10 @@
def __str__(self):
return "" % self.Class
+ def type(self):
+ #if implements call its function
+ return 'object'
+
class W_Arguments(W_Object):
def __init__(self, callee, args):
@@ -207,6 +214,9 @@
#print "* end of function call return = ", val
return val
+ def type(self):
+ return 'function'
+
class W_Array(W_Object):
def __init__(self, items):
W_Object.__init__(self)
@@ -238,6 +248,10 @@
def ToString(self):
return "undefined"
+
+ def type(self):
+ return 'undefined'
+
class W_Null(W_Root):
def __str__(self):
@@ -246,6 +260,9 @@
def ToBoolean(self):
return False
+ def type(self):
+ return 'object'
+
class W_Boolean(W_Primitive):
def __init__(self, boolval):
self.boolval = bool(boolval)
@@ -262,7 +279,10 @@
def ToBoolean(self):
return self.boolval
-
+
+ def type(self):
+ return 'boolean'
+
class W_String(W_Primitive):
def __init__(self, strval):
self.strval = strval
@@ -276,6 +296,9 @@
def ToBoolean(self):
return bool(self.strval)
+ def type(self):
+ return 'string'
+
class W_Number(W_Primitive):
def __init__(self, floatval):
@@ -300,6 +323,8 @@
def Get(self, name):
return w_Undefined
+ def type(self):
+ return 'number'
class W_Builtin(W_Root):
def __init__(self, builtinfunction, context=False, args=0):
@@ -316,7 +341,10 @@
py_args.append(args[i])
res = self.builtinfunction(*py_args)
return res
-
+
+ def type(self):
+ return 'builtin'
+
class W_List(W_Root):
def __init__(self, list_w):
self.list_w = list_w
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Fri Jan 12 18:13:42 2007
@@ -335,11 +335,10 @@
print('out')""", ["out"])
def test_typeof(self):
- py.test.skip(" TODO: needed for mozilla test suite")
- self.assert_prints("""
- var x = 3
- typeof x ==
- """)
+ self.assert_result("""
+ var x = 3;
+ typeof x == 'number'
+ """, W_Boolean(True))
def test_switch(self):
py.test.skip(" TODO: needed for mozilla test suite")
From ericvrp at codespeak.net Fri Jan 12 18:17:33 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 12 Jan 2007 18:17:33 +0100 (CET)
Subject: [pypy-svn] r36600 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070112171733.C1D0B1007C@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 12 18:17:17 2007
New Revision: 36600
Modified:
pypy/dist/pypy/jit/codegen/llvm/compatibility.py
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
Log:
Remaining fixes to have all test_genc_ts tests pass on either llvm 1.9 or 2.0
Modified: pypy/dist/pypy/jit/codegen/llvm/compatibility.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/compatibility.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/compatibility.py Fri Jan 12 18:17:17 2007
@@ -7,7 +7,7 @@
if llvm_version() < 2.0:
icmp = scmp = ucmp = fcmp = 'set'
inttoptr = trunc = zext = bitcast = 'cast'
- shr_prefix = ('', '')
+ shr_prefix = ['', '']
i8 = 'ubyte'
i16 = 'short'
i32 = 'int'
@@ -22,7 +22,7 @@
trunc = 'trunc'
zext = 'zext'
bitcast = 'bitcast'
- shr_prefix = ('l', 'a')
+ shr_prefix = ['l', 'a']
define = 'define'
i8 = 'i8'
i16 = 'i16'
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Fri Jan 12 18:17:17 2007
@@ -1,6 +1,7 @@
import py, os
from pypy.rlib.objectmodel import specialize
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rlib.rarithmetic import intmask
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.llvm import llvmjit
@@ -180,13 +181,13 @@
signed = False
def __init__(self, value):
- self.value = int(value)
+ self.value = value
def operand2(self):
return str(self.value)
def get_integer_value(self):
- return self.value
+ return intmask(self.value)
class FloatConst(GenericConst):
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Fri Jan 12 18:17:17 2007
@@ -5,10 +5,6 @@
from pypy.jit.codegen.llvm.llvmjit import llvm_version, MINIMAL_VERSION
-skip_passing = False
-skip_failing = True
-
-
class LLVMTimeshiftingTestMixin(I386TimeshiftingTestMixin):
RGenOp = RLLVMGenOp
@@ -38,56 +34,3 @@
test_array_of_voids = skip
test_merge_structures = skip
test_green_char_at_merge = skip
-
- if skip_passing:
- test_very_simple = skip
- test_convert_const_to_redbox = skip
- test_simple_opt_const_propagation2 = skip
- test_simple_opt_const_propagation1 = skip
- test_loop_folding = skip
- test_loop_merging = skip
- test_two_loops_merging = skip
- test_convert_greenvar_to_redvar = skip
- test_green_across_split = skip
- test_merge_const_before_return = skip
- test_merge_3_redconsts_before_return = skip
- test_arith_plus_minus = skip
- test_plus_minus_all_inlined = skip
- test_call_simple = skip
- test_call_2 = skip
- test_call_3 = skip
- test_call_4 = skip
- test_void_call = skip
- test_green_call = skip
- test_split_on_green_return = skip
- test_recursive_call = skip
- test_simple_indirect_call = skip
- test_normalize_indirect_call = skip
- test_normalize_indirect_call_more = skip
- test_green_red_mismatch_in_call = skip
- test_red_call_ignored_result = skip
- test_simple_struct = skip
- test_simple_array = skip
- test_setarrayitem = skip
- test_degenerated_before_return = skip
- test_degenerated_before_return_2 = skip
- test_degenerated_via_substructure = skip
- test_red_virtual_container = skip
- test_red_propagate = skip
- test_red_subcontainer = skip
- test_red_subcontainer_cast = skip
- test_degenerated_at_return = skip
- test_degenerate_with_voids = skip
- test_red_array = skip
- test_red_struct_array = skip
- test_red_varsized_struct = skip
- test_array_of_voids = skip
- test_green_with_side_effects = skip
- test_residual_red_call = skip
- test_merge_structures = skip
- test_simple_meth = skip
- test_simple_red_meth = skip
-
- #failing...
- if skip_failing:
- test_compile_time_const_tuple = skip
From cfbolz at codespeak.net Fri Jan 12 18:32:40 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 18:32:40 +0100 (CET)
Subject: [pypy-svn] r36601 - in pypy/dist/pypy/config: . test
Message-ID: <20070112173240.4D4C710077@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 18:32:30 2007
New Revision: 36601
Modified:
pypy/dist/pypy/config/config.py
pypy/dist/pypy/config/test/test_config.py
Log:
add a "suggests" to options: if a ChoiceOption suggests another option, it will
be set, but can be overridden.
Modified: pypy/dist/pypy/config/config.py
==============================================================================
--- pypy/dist/pypy/config/config.py (original)
+++ pypy/dist/pypy/config/config.py Fri Jan 12 18:32:30 2007
@@ -79,10 +79,10 @@
child = getattr(self._cfgimpl_descr, name)
oldowner = self._cfgimpl_value_owners[child._name]
oldvalue = getattr(self, name)
- if oldvalue != value and oldowner != "default":
+ if oldvalue != value and oldowner not in ("default", "suggested"):
if who == "default":
return
- raise ValueError('can not override value %s for option %s' %
+ raise ValueError('cannot override value %s for option %s' %
(value, name))
child.setoption(self, value, who)
self._cfgimpl_value_owners[name] = who
@@ -288,9 +288,11 @@
class BoolOption(Option):
def __init__(self, name, doc, default=None, requires=None,
+ suggests=None,
cmdline=DEFAULT_OPTION_NAME, negation=True):
super(BoolOption, self).__init__(name, doc, cmdline=cmdline)
self._requires = requires
+ self._suggests = suggests
self.default = default
self.negation = negation
@@ -304,6 +306,11 @@
toplevel = config._cfgimpl_get_toplevel()
homeconfig, name = toplevel._cfgimpl_get_home_by_path(path)
homeconfig.setoption(name, reqvalue, who)
+ if value and self._suggests is not None:
+ for path, reqvalue in self._suggests:
+ toplevel = config._cfgimpl_get_toplevel()
+ homeconfig, name = toplevel._cfgimpl_get_home_by_path(path)
+ homeconfig.setoption(name, reqvalue, "suggested")
super(BoolOption, self).setoption(config, value, who)
def add_optparse_option(self, argnames, parser, config):
Modified: pypy/dist/pypy/config/test/test_config.py
==============================================================================
--- pypy/dist/pypy/config/test/test_config.py (original)
+++ pypy/dist/pypy/config/test/test_config.py Fri Jan 12 18:32:30 2007
@@ -444,3 +444,18 @@
assert c2.s1.a
c2.int = 44 # does not crash
+def test_suggests():
+ descr = OptionDescription("test", '', [
+ BoolOption("toplevel", "", default=False),
+ BoolOption("opt", "", default=False,
+ suggests=[("toplevel", True)])
+ ])
+ c = Config(descr)
+ assert not c.toplevel
+ assert not c.opt
+ c.opt = True
+ assert c.opt
+ assert c.toplevel
+ # does not crash
+ c.toplevel = False
+ assert not c.toplevel
From cfbolz at codespeak.net Fri Jan 12 18:34:59 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 18:34:59 +0100 (CET)
Subject: [pypy-svn] r36602 - in pypy/dist/pypy/config: . test
Message-ID: <20070112173459.2BF2A10078@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 18:34:53 2007
New Revision: 36602
Modified:
pypy/dist/pypy/config/config.py
pypy/dist/pypy/config/test/test_config.py
Log:
test + fix
Modified: pypy/dist/pypy/config/config.py
==============================================================================
--- pypy/dist/pypy/config/config.py (original)
+++ pypy/dist/pypy/config/config.py Fri Jan 12 18:34:53 2007
@@ -80,7 +80,7 @@
oldowner = self._cfgimpl_value_owners[child._name]
oldvalue = getattr(self, name)
if oldvalue != value and oldowner not in ("default", "suggested"):
- if who == "default":
+ if who in ("default", "suggested"):
return
raise ValueError('cannot override value %s for option %s' %
(value, name))
Modified: pypy/dist/pypy/config/test/test_config.py
==============================================================================
--- pypy/dist/pypy/config/test/test_config.py (original)
+++ pypy/dist/pypy/config/test/test_config.py Fri Jan 12 18:34:53 2007
@@ -459,3 +459,12 @@
# does not crash
c.toplevel = False
assert not c.toplevel
+
+ c = Config(descr)
+ c.toplevel = False
+ assert not c.toplevel
+ # does not crash
+ c.opt = True
+ assert c.opt
+ assert not c.toplevel
+
From cfbolz at codespeak.net Fri Jan 12 18:37:19 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 18:37:19 +0100 (CET)
Subject: [pypy-svn] r36603 - pypy/dist/pypy/config
Message-ID: <20070112173719.6707210078@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 18:37:14 2007
New Revision: 36603
Modified:
pypy/dist/pypy/config/pypyoption.py
Log:
--faassen and --allworkingmodules use suggest now
Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py (original)
+++ pypy/dist/pypy/config/pypyoption.py Fri Jan 12 18:37:14 2007
@@ -80,7 +80,7 @@
BoolOption("allworkingmodules", "use as many working modules as possible",
default=False,
cmdline="--allworkingmodules",
- requires=[("objspace.usemodules.%s" % (modname, ), True)
+ suggests=[("objspace.usemodules.%s" % (modname, ), True)
for modname in working_modules
if modname in all_modules],
negation=False),
@@ -168,7 +168,7 @@
BoolOption("allopts",
"enable all thought-to-be-working optimizations",
default=False,
- requires=[("objspace.opcodes.CALL_LIKELY_BUILTIN", True),
+ suggests=[("objspace.opcodes.CALL_LIKELY_BUILTIN", True),
("translation.withsmallfuncsets", 5),
("translation.profopt",
"-c 'from richards import main;main(); from test import pystone; pystone.main()'"),
From antocuni at codespeak.net Fri Jan 12 18:38:38 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 18:38:38 +0100 (CET)
Subject: [pypy-svn] r36604 - in pypy/dist/pypy/translator/backendopt: . test
Message-ID: <20070112173838.99F4310078@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 18:38:29 2007
New Revision: 36604
Modified:
pypy/dist/pypy/translator/backendopt/malloc.py
pypy/dist/pypy/translator/backendopt/test/test_malloc.py
Log:
bugfix, and the corresponding test.
Modified: pypy/dist/pypy/translator/backendopt/malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/malloc.py Fri Jan 12 18:38:29 2007
@@ -550,8 +550,7 @@
def flatten(self, TYPE):
for name, (FIELDTYPE, default) in self._get_fields(TYPE).iteritems():
key = self.key_for_field_access(TYPE, name)
- example = FIELDTYPE._defl()
- constant = Constant(example)
+ constant = Constant(default)
constant.concretetype = FIELDTYPE
self.flatconstants[key] = constant
self.flatnames.append(key)
Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Fri Jan 12 18:38:29 2007
@@ -341,3 +341,14 @@
s = ootype.new(FOO)
return bool(s)
self.check(fn, [], [], True)
+
+ def test_classattr_as_defaults(self):
+ class Bar:
+ foo = 41
+
+ def fn():
+ x = Bar()
+ x.foo += 1
+ return x.foo
+ self.check(fn, [], [], 42)
+
From fijal at codespeak.net Fri Jan 12 18:51:23 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 18:51:23 +0100 (CET)
Subject: [pypy-svn] r36605 - pypy/dist/pypy/annotation
Message-ID: <20070112175123.5A4F210077@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 18:51:13 2007
New Revision: 36605
Modified:
pypy/dist/pypy/annotation/signature.py
Log:
Added annotation function which will (hopefully) replace annotation_from_example approach and his friends
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Fri Jan 12 18:51:13 2007
@@ -2,11 +2,21 @@
import types
from pypy.annotation.model import SomeBool, SomeInteger, SomeString,\
SomeFloat, SomeList, SomeDict, s_None, SomeExternalObject,\
- SomeObject, SomeInstance
+ SomeObject, SomeInstance, lltype_to_annotation
from pypy.annotation.classdef import ClassDef, InstanceSource
from pypy.annotation.listdef import ListDef, MOST_GENERAL_LISTDEF
from pypy.annotation.dictdef import DictDef, MOST_GENERAL_DICTDEF
+def annotation(t, bookkeeper=None):
+ from pypy.rpython.lltypesystem import lltype
+
+ if isinstance(t, SomeObject):
+ return t
+ elif isinstance(t, lltype.LowLevelType):
+ return lltype_to_annotation(t)
+ else:
+ return annotationoftype(t, bookkeeper)
+
def annotationoftype(t, bookkeeper=False):
from pypy.annotation.builtin import BUILTIN_ANALYZERS
from pypy.annotation.builtin import EXTERNAL_TYPE_ANALYZERS
@@ -30,6 +40,15 @@
# can't do tuple
elif t is types.NoneType:
return s_None
+ elif isinstance(t, list):
+ assert len(t) == 1, "We do not support type joining in list"
+ return SomeList(ListDef(None, annotation(t[0])))
+ elif isinstance(t, tuple):
+ return SomeTuple(tuple([annotation(i) for i in t]))
+ elif isinstance(t, dict):
+ assert len(t) == 1, "We do not support type joining in dict"
+ return SomeDict(DictDef(None, annotation(t.keys()[0]),
+ annotation(t.values()[0])))
elif t in EXTERNAL_TYPE_ANALYZERS:
return SomeExternalObject(t)
elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy):
@@ -56,20 +75,17 @@
for i, argtype in enumerate(self.argtypes):
if isinstance(argtype, (types.FunctionType, types.MethodType)):
argtype = argtype(*inputcells)
- if isinstance(argtype, annmodel.SomeObject):
- args_s.append(argtype)
- elif isinstance(argtype, lltype.LowLevelType):
- if argtype is lltype.Void:
- # XXX the mapping between Void and annotation
- # is not quite well defined
- s_input = inputcells[i]
- assert isinstance(s_input, annmodel.SomePBC)
- assert s_input.is_constant()
- args_s.append(s_input)
- else:
- args_s.append(annmodel.lltype_to_annotation(argtype))
+ if isinstance(argtype, lltype.LowLevelType) and\
+ argtype is lltype.Void:
+ # XXX the mapping between Void and annotation
+ # is not quite well defined
+ s_input = inputcells[i]
+ assert isinstance(s_input, annmodel.SomePBC)
+ assert s_input.is_constant()
+ args_s.append(s_input)
+ args_s.append(annmodel.lltype_to_annotation(argtype))
else:
- args_s.append(funcdesc.bookkeeper.valueoftype(argtype))
+ args_s.append(annotation(argtype, bookkeeper=funcdesc.bookkeeper))
if len(inputcells) != len(args_s):
raise Exception("%r: expected %d args, got %d" % (funcdesc,
len(args_s),
From arigo at codespeak.net Fri Jan 12 19:05:09 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Fri, 12 Jan 2007 19:05:09 +0100 (CET)
Subject: [pypy-svn] r36607 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070112180509.20AB210078@code0.codespeak.net>
Author: arigo
Date: Fri Jan 12 19:04:55 2007
New Revision: 36607
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Fix the generation of binary operations. Try hard to generate the
smallest possible amount of MOVs around each operation individually.
Maybe possibly even succeed in doing so.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Fri Jan 12 19:04:55 2007
@@ -39,7 +39,6 @@
return # simple operation whose result is not used anyway
op = allocator.load_location_with(loc, self.x)
self.emit(allocator.mc, op)
- allocator.store_back_location(loc, op)
class OpSameAs(Op1):
clobbers_cc = False
@@ -78,6 +77,7 @@
mc.CMP(x, imm8(0))
class Op2(Operation):
+ commutative = False
def __init__(self, x, y):
self.x = x
self.y = y
@@ -86,22 +86,66 @@
allocator.using(self.y)
def generate(self, allocator):
try:
- loc = allocator.var2loc[self]
+ dstop = allocator.get_operand(self)
except KeyError:
return # simple operation whose result is not used anyway
- op1 = allocator.load_location_with(loc, self.x)
+ op1 = allocator.get_operand(self.x)
op2 = allocator.get_operand(self.y)
- self.emit(allocator.mc, op1, op2)
- allocator.store_back_location(loc, op1)
+ # now all of dstop, op1 and op2 may alias each other and be in
+ # a register or in the stack... finding a correct and encodable
+ # combination of instructions is loads of fun
+ mc = allocator.mc
+ if dstop == op1:
+ case = 1 # optimize for this common case
+ elif self.commutative and dstop == op2:
+ op1, op2 = op2, op1
+ case = 1
+ elif isinstance(dstop, REG):
+ if dstop != op2:
+ # REG = OPERATION(op1, op2) with op2 != REG
+ case = 2
+ else:
+ # REG = OPERATION(op1, REG)
+ case = 3
+ elif isinstance(op1, REG) and isinstance(op2, REG):
+ # STACK = OPERATION(REG, REG)
+ case = 2
+ else:
+ case = 3
+ # this is a separator line but a blank line doesn't look nice here
+ if case == 1:
+ # dstop == op1
+ try:
+ self.emit(mc, op1, op2)
+ except FailedToImplement: # emit(STACK, STACK) combination
+ mc.MOV(ecx, op2)
+ self.emit(mc, op1, ecx)
+ elif case == 2:
+ # this case works for:
+ # * REG = OPERATION(op1, op2) with op2 != REG
+ # * STACK = OPERATION(REG, REG)
+ mc.MOV(dstop, op1)
+ self.emit(mc, dstop, op2)
+ else:
+ # most general case
+ mc.MOV(ecx, op1)
+ self.emit(mc, ecx, op2)
+ mc.MOV(dstop, ecx)
class OpIntAdd(Op2):
opname = 'int_add'
emit = staticmethod(I386CodeBuilder.ADD)
+ commutative = True
class OpIntSub(Op2):
opname = 'int_sub'
emit = staticmethod(I386CodeBuilder.SUB)
+class OpIntMul(Op2):
+ opname = 'int_mul'
+ emit = staticmethod(I386CodeBuilder.IMUL)
+ commutative = True
+
class OpCompare2(Op2):
result_kind = RK_CC
def generate(self, allocator):
@@ -409,18 +453,11 @@
def load_location_with(self, loc, gv_source):
dstop = self.operands[loc]
- if not isinstance(dstop, REG):
- dstop = ecx
srcop = self.get_operand(gv_source)
if srcop != dstop:
self.mc.MOV(dstop, srcop)
return dstop
- def store_back_location(self, loc, operand):
- dstop = self.operands[loc]
- if operand != dstop:
- self.mc.MOV(dstop, operand)
-
def generate_initial_moves(self):
initial_moves = self.initial_moves
# first make sure that the reserved stack frame is big enough
@@ -433,6 +470,7 @@
if last_n >= 0:
self.mc.LEA(esp, stack_op(last_n))
# XXX naive algo for now
+ # XXX at least remove moves that don't move anything!
for loc, srcoperand in initial_moves:
self.mc.PUSH(srcoperand)
initial_moves.reverse()
@@ -523,6 +561,14 @@
self.operations.append(JumpIf(gv_condition, newbuilder, negate=False))
return newbuilder
+ def finish_and_goto(self, outputargs_gv, targetlbl):
+ operands = targetlbl.inputoperands
+ if operands is None:
+ raise NotImplementedError
+ mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands)
+ mc.JMP(rel32(targetlbl.targetaddr))
+ self.rgenop.close_mc(mc)
+
def finish_and_return(self, sigtoken, gv_returnvar):
mc = self.generate_block_code([gv_returnvar], [gv_returnvar], [eax])
# --- epilogue ---
From pedronis at codespeak.net Fri Jan 12 19:13:28 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 12 Jan 2007 19:13:28 +0100 (CET)
Subject: [pypy-svn] r36609 - in pypy/dist/pypy/jit: codegen codegen/llgraph
timeshifter timeshifter/test
Message-ID: <20070112181328.D319010080@code0.codespeak.net>
Author: pedronis
Date: Fri Jan 12 19:13:10 2007
New Revision: 36609
Modified:
pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
pypy/dist/pypy/jit/codegen/model.py
pypy/dist/pypy/jit/timeshifter/hrtyper.py
pypy/dist/pypy/jit/timeshifter/rcontainer.py
pypy/dist/pypy/jit/timeshifter/rtimeshift.py
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
(arre, pedronis)
first test passing reading values out of jit frames for virtualizable accessed during residual calls.
Next step to generalize this to support lazy forcing of virtual struct "pointed to" from a virtualizable and accessed.
Modified: pypy/dist/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/dist/pypy/jit/codegen/llgraph/llimpl.py Fri Jan 12 19:13:10 2007
@@ -193,7 +193,11 @@
elif T == llmemory.Address:
return llmemory.cast_ptr_to_adr(c.value)
else:
- return lltype.cast_primitive(T, c.value)
+ if lltype.typeOf(c.value) == llmemory.Address:
+ value = llmemory.cast_adr_to_int(c.value)
+ else:
+ value = c.value
+ return lltype.cast_primitive(T, value)
def isconst(gv_value):
c = from_opaque_object(gv_value)
Modified: pypy/dist/pypy/jit/codegen/model.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/model.py (original)
+++ pypy/dist/pypy/jit/codegen/model.py Fri Jan 12 19:13:10 2007
@@ -171,6 +171,15 @@
def start_writing(self):
'''Start a builder returned by jump_if_xxx(), or resumes a paused
builder.'''
+
+
+ # read frame var support
+
+ def get_frame_base(self):
+ pass
+
+ def get_frame_info(self):
+ pass
class GenLabel(object):
'''A "smart" label. Represents an address of the start of a basic
Modified: pypy/dist/pypy/jit/timeshifter/hrtyper.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/hrtyper.py (original)
+++ pypy/dist/pypy/jit/timeshifter/hrtyper.py Fri Jan 12 19:13:10 2007
@@ -680,8 +680,8 @@
PTRTYPE = originalconcretetype(hop.args_s[0])
if PTRTYPE.TO._hints.get('virtualizable', False):
# xxx optimisation: do this folding already at hint-annotation time!
- if hop.args_v[1].value == 'access':
- ACCESSPTR = PTRTYPE.TO.access
+ if hop.args_v[1].value == 'vable_access':
+ ACCESSPTR = PTRTYPE.TO.vable_access
access_repr = self.getredrepr(ACCESSPTR)
return hop.inputconst(access_repr, lltype.nullptr(ACCESSPTR.TO))
@@ -690,7 +690,7 @@
green_void_repr)
v_argbox = hop.llops.as_ptrredbox(v_argbox)
c_deepfrozen = inputconst(lltype.Bool, hop.args_s[0].deepfrozen)
- structdesc = rcontainer.StructTypeDesc(self.RGenOp, PTRTYPE.TO)
+ structdesc = rcontainer.StructTypeDesc(self, PTRTYPE.TO)
fielddesc = structdesc.getfielddesc(c_fieldname.value)
if fielddesc is None: # Void field
return
@@ -710,7 +710,7 @@
v_argbox, v_index = hop.inputargs(self.getredrepr(PTRTYPE),
self.getredrepr(lltype.Signed))
c_deepfrozen = inputconst(lltype.Bool, hop.args_s[0].deepfrozen)
- fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
+ fielddesc = rcontainer.ArrayFieldDesc(self, PTRTYPE.TO)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
@@ -727,7 +727,7 @@
ts = self
[v_argbox] = hop.inputargs(self.getredrepr(PTRTYPE))
- fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
+ fielddesc = rcontainer.ArrayFieldDesc(self, PTRTYPE.TO)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
@@ -768,7 +768,7 @@
self.getredrepr(VALUETYPE)
)
v_destbox = hop.llops.as_ptrredbox(v_destbox)
- structdesc = rcontainer.StructTypeDesc(self.RGenOp, PTRTYPE.TO)
+ structdesc = rcontainer.StructTypeDesc(self, PTRTYPE.TO)
fielddesc = structdesc.getfielddesc(c_fieldname.value)
assert fielddesc is not None # skipped above
c_fielddesc = inputconst(lltype.Void, fielddesc)
@@ -788,7 +788,7 @@
v_argbox, v_index, v_valuebox= hop.inputargs(self.getredrepr(PTRTYPE),
self.getredrepr(lltype.Signed),
self.getredrepr(VALUETYPE))
- fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
+ fielddesc = rcontainer.ArrayFieldDesc(self, PTRTYPE.TO)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
@@ -805,8 +805,7 @@
v_argbox, c_fieldname = hop.inputargs(self.getredrepr(PTRTYPE),
green_void_repr)
v_argbox = hop.llops.as_ptrredbox(v_argbox)
- fielddesc = rcontainer.NamedFieldDesc(self.RGenOp, PTRTYPE,
- c_fieldname.value)
+ fielddesc = rcontainer.NamedFieldDesc(self, PTRTYPE, c_fieldname.value)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
@@ -820,7 +819,7 @@
ts = self
v_argbox, v_index = hop.inputargs(self.getredrepr(PTRTYPE),
self.getredrepr(lltype.Signed))
- fielddesc = rcontainer.ArrayFieldDesc(self.RGenOp, PTRTYPE.TO)
+ fielddesc = rcontainer.ArrayFieldDesc(self, PTRTYPE.TO)
c_fielddesc = inputconst(lltype.Void, fielddesc)
s_fielddesc = ts.rtyper.annotator.bookkeeper.immutablevalue(fielddesc)
v_jitstate = hop.llops.getjitstate()
@@ -846,9 +845,9 @@
PTRTYPE = originalconcretetype(hop.s_result)
TYPE = PTRTYPE.TO
if isinstance(TYPE, lltype.Struct):
- contdesc = rcontainer.StructTypeDesc(self.RGenOp, TYPE)
+ contdesc = rcontainer.StructTypeDesc(self, TYPE)
else:
- contdesc = rcontainer.ArrayFieldDesc(self.RGenOp, TYPE)
+ contdesc = rcontainer.ArrayFieldDesc(self, TYPE)
c_contdesc = inputconst(lltype.Void, contdesc)
s_contdesc = ts.rtyper.annotator.bookkeeper.immutablevalue(contdesc)
v_jitstate = hop.llops.getjitstate()
@@ -1506,8 +1505,10 @@
if not T._hints.get('virtualizable', False):
RedRepr.build_portal_arg_helpers(self)
return
-
- names = unrolling_iterable([name for name in T._names if name != 'access'])
+
+
+ names = unrolling_iterable([name for name in T._names
+ if name not in rcontainer.VABLEFIELDS])
def collect_residual_args(v):
t = (v,)
for name in names:
@@ -1524,7 +1525,7 @@
def make_arg_redbox(jitstate, inputargs_gv, i):
box = typedesc.factory()
jitstate.add_virtualizable(box)
- j = 1
+ j = rcontainer.NVABLEFIELDS
content = box.content
assert isinstance(content, rcontainer.VirtualStruct)
content_boxes = content.content_boxes
@@ -1537,13 +1538,13 @@
content_boxes[j].genvar = gv_outside
return box
self.make_arg_redbox = make_arg_redbox
- make_arg_redbox.consumes = len(T._names)
+ make_arg_redbox.consumes = len(T._names)-rcontainer.NVABLEFIELDS+1
def gettypedesc(self):
if self.typedesc is None:
- ts = self.hrtyper
+ hrtyper = self.hrtyper
T = self.original_concretetype.TO
- self.typedesc = rcontainer.StructTypeDesc(ts.RGenOp, T)
+ self.typedesc = rcontainer.StructTypeDesc(hrtyper, T)
return self.typedesc
def create(self, hop):
@@ -1559,7 +1560,7 @@
if T._hints.get('virtualizable', False):
getredrepr = self.hrtyper.getredrepr
for name in T._names:
- if name == 'access':
+ if name in rcontainer.VABLEFIELDS:
continue
FIELDTYPE = getattr(T, name)
argtypes += getredrepr(FIELDTYPE).residual_argtypes()
Modified: pypy/dist/pypy/jit/timeshifter/rcontainer.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rcontainer.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rcontainer.py Fri Jan 12 19:13:10 2007
@@ -5,6 +5,7 @@
from pypy.jit.timeshifter import rvalue
from pypy.rlib.unroll import unrolling_iterable
+from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem import lloperation
debug_print = lloperation.llop.debug_print
debug_pdb = lloperation.llop.debug_pdb
@@ -37,15 +38,24 @@
# ____________________________________________________________
+VABLEFIELDS = ('vable_base', 'vable_info', 'vable_access')
+NVABLEFIELDS = len(VABLEFIELDS)
+
class StructTypeDesc(object):
__metaclass__ = cachedtype
firstsubstructdesc = None
arrayfielddesc = None
alloctoken = None
varsizealloctoken = None
- materialize = None
+ materialize = None
+
+ base_desc = None
+ info_desc = None
+ access_desc = None
+ gv_access = None
- def __init__(self, RGenOp, TYPE):
+ def __init__(self, hrtyper, TYPE):
+ RGenOp = hrtyper.RGenOp
self.TYPE = TYPE
self.PTRTYPE = lltype.Ptr(TYPE)
self.ptrkind = RGenOp.kindToken(self.PTRTYPE)
@@ -58,10 +68,10 @@
FIELDTYPE = getattr(self.TYPE, name)
if isinstance(FIELDTYPE, lltype.ContainerType):
if isinstance(FIELDTYPE, lltype.Array):
- self.arrayfielddesc = ArrayFieldDesc(RGenOp, FIELDTYPE)
+ self.arrayfielddesc = ArrayFieldDesc(hrtyper, FIELDTYPE)
self.varsizealloctoken = RGenOp.varsizeAllocToken(TYPE)
continue
- substructdesc = StructTypeDesc(RGenOp, FIELDTYPE)
+ substructdesc = StructTypeDesc(hrtyper, FIELDTYPE)
assert name == self.TYPE._names[0], (
"unsupported: inlined substructures not as first field")
fielddescs.extend(substructdesc.fielddescs)
@@ -72,7 +82,7 @@
if FIELDTYPE is lltype.Void:
desc = None
else:
- desc = StructFieldDesc(RGenOp, self.PTRTYPE, name, index)
+ desc = StructFieldDesc(hrtyper, self.PTRTYPE, name, index)
fielddescs.append(desc)
fielddesc_by_name[name] = desc
self.fielddescs = fielddescs
@@ -85,10 +95,35 @@
self.null = self.PTRTYPE._defl()
self.gv_null = RGenOp.constPrebuiltGlobal(self.null)
-
self.virtualizable = TYPE._hints.get('virtualizable', False)
if self.virtualizable:
self.VStructCls = VirtualizableStruct
+ self.base_desc = self.getfielddesc('vable_base')
+ self.info_desc = self.getfielddesc('vable_info')
+ self.access_desc = self.getfielddesc('vable_access')
+ ACCESS = TYPE.vable_access.TO
+ access = lltype.malloc(ACCESS, immortal=True)
+ self.gv_access = RGenOp.constPrebuiltGlobal(access)
+ annhelper = hrtyper.annhelper
+ j = 0
+ def make_get_field(T, j):
+ def get_field(struc):
+ return RGenOp.read_frame_var(T, struc.vable_base,
+ struc.vable_info,
+ j)
+ return get_field
+ s_structtype = annmodel.lltype_to_annotation(self.PTRTYPE)
+ for i in range(NVABLEFIELDS, len(fielddescs)):
+ fielddesc = fielddescs[i]
+ get_field = make_get_field(fielddesc.RESTYPE, j)
+ j += 1
+ s_lltype = annmodel.lltype_to_annotation(fielddesc.RESTYPE)
+ get_field_ptr = annhelper.delayedfunction(get_field,
+ [s_structtype],
+ s_lltype,
+ needtype = True)
+ name = fielddesc.fieldname
+ setattr(access, 'get_'+name, get_field_ptr)
else:
self.VStructCls = VirtualStruct
@@ -136,8 +171,10 @@
__metaclass__ = cachedtype
allow_void = False
virtualizable = False
+ gv_default = None
- def __init__(self, RGenOp, PTRTYPE, RESTYPE):
+ def __init__(self, hrtyper, PTRTYPE, RESTYPE):
+ RGenOp = hrtyper.RGenOp
self.PTRTYPE = PTRTYPE
if isinstance(RESTYPE, lltype.ContainerType):
RESTYPE = lltype.Ptr(RESTYPE)
@@ -148,11 +185,12 @@
self.RESTYPE = RESTYPE
self.ptrkind = RGenOp.kindToken(PTRTYPE)
self.kind = RGenOp.kindToken(RESTYPE)
- self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
+ if self.RESTYPE is not lltype.Void:
+ self.gv_default = RGenOp.constPrebuiltGlobal(self.RESTYPE._defl())
if RESTYPE is lltype.Void and self.allow_void:
pass # no redboxcls at all
elif self.virtualizable:
- self.structdesc = StructTypeDesc(RGenOp, T)
+ self.structdesc = StructTypeDesc(hrtyper, T)
else:
self.redboxcls = rvalue.ll_redboxcls(RESTYPE)
self.immutable = PTRTYPE.TO._hints.get('immutable', False)
@@ -176,11 +214,11 @@
class NamedFieldDesc(FieldDesc):
- def __init__(self, RGenOp, PTRTYPE, name):
- FieldDesc.__init__(self, RGenOp, PTRTYPE, getattr(PTRTYPE.TO, name))
+ def __init__(self, hrtyper, PTRTYPE, name):
+ FieldDesc.__init__(self, hrtyper, PTRTYPE, getattr(PTRTYPE.TO, name))
T = self.PTRTYPE.TO
self.fieldname = name
- self.fieldtoken = RGenOp.fieldToken(T, name)
+ self.fieldtoken = hrtyper.RGenOp.fieldToken(T, name)
def compact_repr(self): # goes in ll helper names
return "Fld_%s_in_%s" % (self.fieldname, self.PTRTYPE._short_name())
@@ -201,16 +239,17 @@
class StructFieldDesc(NamedFieldDesc):
- def __init__(self, RGenOp, PTRTYPE, name, index):
- NamedFieldDesc.__init__(self, RGenOp, PTRTYPE, name)
+ def __init__(self, hrtyper, PTRTYPE, name, index):
+ NamedFieldDesc.__init__(self, hrtyper, PTRTYPE, name)
self.fieldindex = index
class ArrayFieldDesc(FieldDesc):
allow_void = True
- def __init__(self, RGenOp, TYPE):
+ def __init__(self, hrtyper, TYPE):
assert isinstance(TYPE, lltype.Array)
- FieldDesc.__init__(self, RGenOp, lltype.Ptr(TYPE), TYPE.OF)
+ FieldDesc.__init__(self, hrtyper, lltype.Ptr(TYPE), TYPE.OF)
+ RGenOp = hrtyper.RGenOp
self.arraytoken = RGenOp.arrayToken(TYPE)
self.varsizealloctoken = RGenOp.varsizeAllocToken(TYPE)
self.indexkind = RGenOp.kindToken(lltype.Signed)
@@ -371,7 +410,7 @@
fielddescs = self.typedesc.fielddescs
boxes = self.content_boxes
gv_outside = boxes[-1].genvar
- for i in range(1, len(fielddescs)):
+ for i in range(NVABLEFIELDS, len(fielddescs)):
fielddesc = fielddescs[i]
box = boxes[i]
fielddesc.generate_set(jitstate, gv_outside,
@@ -381,11 +420,51 @@
fielddescs = self.typedesc.fielddescs
boxes = self.content_boxes
boxes[-1].genvar = gv_outside
- for i in range(1, len(fielddescs)):
+ for i in range(NVABLEFIELDS, len(fielddescs)):
fielddesc = fielddescs[i]
boxes[i] = fielddesc.generate_get(jitstate, gv_outside)
jitstate.add_virtualizable(self.ownbox)
+ def prepare_for_residual_call(self, jitstate, gv_base):
+ typedesc = self.typedesc
+ builder = jitstate.curbuilder
+ gv_outside = self.content_boxes[-1].genvar
+ if gv_outside is not typedesc.gv_null:
+ base_desc = typedesc.base_desc
+ assert base_desc is not None
+ base_token = base_desc.fieldtoken
+ builder.genop_setfield(base_token, gv_outside, gv_base)
+ # xxx recursive and virtual stuff
+ boxes = self.content_boxes
+ vars_gv = []
+ n = len(boxes)
+ for i in range(NVABLEFIELDS, n-1):
+ box = boxes[i]
+ assert box.genvar
+ vars_gv.append(box.genvar)
+ gv_info = builder.get_frame_info(vars_gv)
+ info_token = typedesc.info_desc.fieldtoken
+ access_token = typedesc.access_desc.fieldtoken
+ builder.genop_setfield(info_token, gv_outside, gv_info)
+ builder.genop_setfield(access_token, gv_outside, typedesc.gv_access)
+
+ def after_residual_call(self, jitstate):
+ typedesc = self.typedesc
+ builder = jitstate.curbuilder
+ gv_outside = self.content_boxes[-1].genvar
+ if gv_outside is not typedesc.gv_null:
+ base_desc = typedesc.base_desc
+ assert base_desc is not None
+ base_token = typedesc.base_desc.fieldtoken
+ info_token = typedesc.info_desc.fieldtoken
+ access_token = typedesc.access_desc.fieldtoken
+ gv_base_null = typedesc.base_desc.gv_default
+ gv_info_null = typedesc.info_desc.gv_default
+ gv_access_null = typedesc.access_desc.gv_default
+ builder.genop_setfield(base_token, gv_outside, gv_base_null)
+ builder.genop_setfield(info_token, gv_outside, gv_info_null)
+ builder.genop_setfield(access_token, gv_outside, gv_access_null)
+
# ____________________________________________________________
class FrozenPartialDataStruct(AbstractContainer):
Modified: pypy/dist/pypy/jit/timeshifter/rtimeshift.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/rtimeshift.py (original)
+++ pypy/dist/pypy/jit/timeshifter/rtimeshift.py Fri Jan 12 19:13:10 2007
@@ -455,6 +455,7 @@
def __init__(self, RGenOp, FUNCTYPE):
self.sigtoken = RGenOp.sigToken(FUNCTYPE)
self.result_kind = RGenOp.kindToken(FUNCTYPE.RESULT)
+ # xxx what if the result is virtualizable?
self.redboxbuilder = rvalue.ll_redboxbuilder(FUNCTYPE.RESULT)
def _freeze_(self):
@@ -462,10 +463,12 @@
def ll_gen_residual_call(jitstate, calldesc, funcbox):
builder = jitstate.curbuilder
+ jitstate.prepare_for_residual_call()
gv_funcbox = funcbox.getgenvar(jitstate)
argboxes = jitstate.frame.local_boxes
args_gv = [argbox.getgenvar(jitstate) for argbox in argboxes]
gv_result = builder.genop_call(calldesc.sigtoken, gv_funcbox, args_gv)
+ jitstate.after_residual_call()
return calldesc.redboxbuilder(calldesc.result_kind, gv_result)
@@ -879,6 +882,25 @@
content.store_back(self)
return incoming
+ def prepare_for_residual_call(self):
+ virtualizables = self.virtualizables
+ if virtualizables:
+ builder = self.curbuilder
+ gv_base = builder.get_frame_base()
+ for virtualizable_box in virtualizables.keys():
+ content = virtualizable_box.content
+ assert isinstance(content, rcontainer.VirtualizableStruct)
+ content.prepare_for_residual_call(self, gv_base)
+
+ def after_residual_call(self):
+ virtualizables = self.virtualizables
+ if virtualizables:
+ builder = self.curbuilder
+ for virtualizable_box in virtualizables.keys():
+ content = virtualizable_box.content
+ assert isinstance(content, rcontainer.VirtualizableStruct)
+ content.after_residual_call(self)
+
def freeze(self, memo):
result = FrozenJITState()
result.fz_frame = self.frame.freeze(memo)
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Fri Jan 12 19:13:10 2007
@@ -1,6 +1,6 @@
from pypy.jit.hintannotator.annotator import HintAnnotatorPolicy
from pypy.jit.timeshifter.test.test_portal import PortalTest, P_NOVIRTUAL
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
import py
@@ -37,7 +37,9 @@
)
XY.become(lltype.GcStruct('xy',
- ('access', lltype.Ptr(XY_ACCESS)),
+ ('vable_base', llmemory.Address),
+ ('vable_info', llmemory.GCREF),
+ ('vable_access', lltype.Ptr(XY_ACCESS)),
('x', lltype.Signed),
('y', lltype.Signed),
hints = {'virtualizable': True}
@@ -47,7 +49,9 @@
('w', lltype.Signed))
XP.become(lltype.GcStruct('xp',
- ('access', lltype.Ptr(XP_ACCESS)),
+ ('vable_base', llmemory.Address),
+ ('vable_info', llmemory.GCREF),
+ ('vable_access', lltype.Ptr(XP_ACCESS)),
('x', lltype.Signed),
('p', PS),
hints = {'virtualizable': True}
@@ -59,12 +63,12 @@
def test_simple_explicit(self):
def f(xy):
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
x = xy_access.get_x(xy)
else:
x = xy.x
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -73,7 +77,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
return f(xy)
@@ -89,17 +93,17 @@
def test_simple_explicit_set(self):
def f(xy):
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
x = xy_access.get_x(xy)
else:
x = xy.x
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
xy_access.set_y(xy, 1)
else:
xy.y = 1
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -108,7 +112,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
return f(xy)
@@ -124,17 +128,17 @@
def test_explicit_set_effect(self):
def f(xy):
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
x = xy_access.get_x(xy)
else:
x = xy.x
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
xy_access.set_y(xy, 3)
else:
xy.y = 3
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -143,7 +147,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
v = f(xy)
@@ -160,7 +164,7 @@
def test_simple_explicit_escape(self):
def f(e, xy):
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
xy_access.set_y(xy, 3)
else:
@@ -170,7 +174,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
e = lltype.malloc(E)
@@ -187,12 +191,12 @@
def test_simple_explicit_return_it(self):
def f(which, xy1, xy2):
- xy1_access = xy1.access
+ xy1_access = xy1.vable_access
if xy1_access:
xy1_access.set_y(xy1, 3)
else:
xy1.y = 3
- xy2_access = xy2.access
+ xy2_access = xy2.vable_access
if xy2_access:
xy2_access.set_y(xy2, 7)
else:
@@ -204,9 +208,9 @@
def main(which, x, y):
xy1 = lltype.malloc(XY)
- xy1.access = lltype.nullptr(XY_ACCESS)
+ xy1.vable_access = lltype.nullptr(XY_ACCESS)
xy2 = lltype.malloc(XY)
- xy2.access = lltype.nullptr(XY_ACCESS)
+ xy2.vable_access = lltype.nullptr(XY_ACCESS)
xy1.x = x
xy1.y = y
xy2.x = y
@@ -224,15 +228,15 @@
def f(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
x = xy_access.get_x(xy)
else:
x = xy.x
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -250,15 +254,15 @@
def f(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
x = xy_access.get_x(xy)
else:
x = xy.x
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -276,12 +280,12 @@
def test_simple_with_struct_explicit(self):
def f(xp):
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
x = xp_access.get_x(xp)
else:
x = xp.x
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
p = xp_access.get_p(xp)
else:
@@ -290,7 +294,7 @@
def main(x, a, b):
xp = lltype.malloc(XP)
- xp.access = lltype.nullptr(XP_ACCESS)
+ xp.vable_access = lltype.nullptr(XP_ACCESS)
xp.x = x
s = lltype.malloc(S)
s.a = a
@@ -306,7 +310,7 @@
def test_simple_with_setting_struct_explicit(self):
def f(xp, s):
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
xp_access.set_p(xp, s)
else:
@@ -315,7 +319,7 @@
x = xp_access.get_x(xp)
else:
x = xp.x
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
p = xp_access.get_p(xp)
else:
@@ -325,7 +329,7 @@
def main(x, a, b):
xp = lltype.malloc(XP)
- xp.access = lltype.nullptr(XP_ACCESS)
+ xp.vable_access = lltype.nullptr(XP_ACCESS)
xp.x = x
s = lltype.malloc(S)
s.a = a
@@ -344,12 +348,12 @@
s = lltype.malloc(S)
s.a = a
s.b = b
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
xp_access.set_p(xp, s)
else:
xp.p = s
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
p = xp_access.get_p(xp)
else:
@@ -363,7 +367,7 @@
def main(x, a, b):
xp = lltype.malloc(XP)
- xp.access = lltype.nullptr(XP_ACCESS)
+ xp.vable_access = lltype.nullptr(XP_ACCESS)
xp.x = x
v = f(xp, a, b)
return v+xp.p.b
@@ -378,17 +382,17 @@
def f(x, a, b):
xp = lltype.malloc(XP)
- xp.access = lltype.nullptr(XP_ACCESS)
+ xp.vable_access = lltype.nullptr(XP_ACCESS)
xp.x = x
s = lltype.malloc(S)
s.a = a
s.b = b
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
xp_access.set_p(xp, s)
else:
xp.p = s
- xp_access = xp.access
+ xp_access = xp.vable_access
if xp_access:
p = xp_access.get_p(xp)
else:
@@ -413,7 +417,7 @@
def f(e):
xy = e.xy
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
xy_access.set_y(xy, 3)
else:
@@ -422,7 +426,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
e = lltype.malloc(E)
@@ -438,17 +442,17 @@
def f(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
e = lltype.malloc(E)
e.xy = xy
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
y = xy.y
- xy_access = xy.access
+ xy_access = xy.vable_access
newy = 2*y
if xy_access:
xy_access.set_y(xy, newy)
@@ -467,7 +471,7 @@
def test_explicit_late_residual_red_call(self):
def g(e):
xy = e.xy
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -476,12 +480,12 @@
def f(e):
xy = e.xy
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
y = xy.y
- xy_access = xy.access
+ xy_access = xy.vable_access
newy = 2*y
if xy_access:
xy_access.set_y(xy, newy)
@@ -492,7 +496,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
e = lltype.malloc(E)
@@ -514,11 +518,11 @@
assert res == 42
def test_explicit_residual_red_call(self):
- py.test.skip("WIP")
+ #py.test.skip("WIP")
def g(e):
xy = e.xy
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
@@ -527,12 +531,12 @@
def f(e):
xy = e.xy
- xy_access = xy.access
+ xy_access = xy.vable_access
if xy_access:
y = xy_access.get_y(xy)
else:
y = xy.y
- xy_access = xy.access
+ xy_access = xy.vable_access
newy = 2*y
if xy_access:
xy_access.set_y(xy, newy)
@@ -543,7 +547,7 @@
def main(x, y):
xy = lltype.malloc(XY)
- xy.access = lltype.nullptr(XY_ACCESS)
+ xy.vable_access = lltype.nullptr(XY_ACCESS)
xy.x = x
xy.y = y
e = lltype.malloc(E)
From pedronis at codespeak.net Fri Jan 12 19:19:03 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Fri, 12 Jan 2007 19:19:03 +0100 (CET)
Subject: [pypy-svn] r36611 - pypy/dist/pypy/jit/timeshifter/test
Message-ID: <20070112181903.CC08D10083@code0.codespeak.net>
Author: pedronis
Date: Fri Jan 12 19:18:55 2007
New Revision: 36611
Modified:
pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
Log:
remove skip
Modified: pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py
==============================================================================
--- pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py (original)
+++ pypy/dist/pypy/jit/timeshifter/test/test_virtualizable.py Fri Jan 12 19:18:55 2007
@@ -518,7 +518,6 @@
assert res == 42
def test_explicit_residual_red_call(self):
- #py.test.skip("WIP")
def g(e):
xy = e.xy
From fijal at codespeak.net Fri Jan 12 19:30:39 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 19:30:39 +0100 (CET)
Subject: [pypy-svn] r36612 - in pypy/dist/pypy: annotation rpython
rpython/module
Message-ID: <20070112183039.BDFB210083@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 19:30:24 2007
New Revision: 36612
Modified:
pypy/dist/pypy/annotation/signature.py
pypy/dist/pypy/rpython/extfunc.py
pypy/dist/pypy/rpython/module/ll_os.py
Log:
Wack a bit to get better feeling of declaring external functions.
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Fri Jan 12 19:30:24 2007
@@ -24,6 +24,17 @@
"""The most precise SomeValue instance that contains all
objects of type t."""
+ if isinstance(t, list):
+ assert len(t) == 1, "We do not support type joining in list"
+ listdef = ListDef(None, annotation(t[0]))
+ listdef.listitem.dont_change_any_more = False
+ return SomeList(listdef)
+ elif isinstance(t, tuple):
+ return SomeTuple(tuple([annotation(i) for i in t]))
+ elif isinstance(t, dict):
+ assert len(t) == 1, "We do not support type joining in dict"
+ return SomeDict(DictDef(None, annotation(t.keys()[0]),
+ annotation(t.values()[0])))
assert isinstance(t, (type, types.ClassType))
if t is bool:
return SomeBool()
@@ -40,15 +51,6 @@
# can't do tuple
elif t is types.NoneType:
return s_None
- elif isinstance(t, list):
- assert len(t) == 1, "We do not support type joining in list"
- return SomeList(ListDef(None, annotation(t[0])))
- elif isinstance(t, tuple):
- return SomeTuple(tuple([annotation(i) for i in t]))
- elif isinstance(t, dict):
- assert len(t) == 1, "We do not support type joining in dict"
- return SomeDict(DictDef(None, annotation(t.keys()[0]),
- annotation(t.values()[0])))
elif t in EXTERNAL_TYPE_ANALYZERS:
return SomeExternalObject(t)
elif bookkeeper and extregistry.is_registered_type(t, bookkeeper.policy):
Modified: pypy/dist/pypy/rpython/extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunc.py (original)
+++ pypy/dist/pypy/rpython/extfunc.py Fri Jan 12 19:30:24 2007
@@ -3,6 +3,7 @@
from pypy.rpython.lltypesystem.lltype import typeOf
from pypy.objspace.flow.model import Constant
from pypy.annotation.model import unionof
+from pypy.annotation.signature import annotation
class ExtFuncEntry(ExtRegistryEntry):
def compute_result_annotation(self, *args_s):
@@ -31,3 +32,18 @@
vlist = [hop.inputconst(typeOf(obj), obj)] + hop.inputargs(*args_r)
hop.exception_is_here()
return hop.genop('direct_call', vlist, r_result)
+
+def register_external(function, args, result, export_name=None,
+ llimpl=None, ooimpl=None):
+
+ class FunEntry(ExtFuncEntry):
+ _about_ = function
+ signature_args = [annotation(arg) for arg in args]
+ signature_result = annotation(result)
+ name=export_name
+ if llimpl:
+ lltypeimpl = llimpl
+ if ooimpl:
+ ootypeimpl = ooimpl
+
+ FunEntry.__name__ = export_name
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jan 12 19:30:24 2007
@@ -20,7 +20,7 @@
from pypy.rlib.rarithmetic import r_longlong
from pypy.tool.staticmethods import ClassMethods
import stat
-from pypy.rpython.extfunc import ExtFuncEntry
+from pypy.rpython.extfunc import ExtFuncEntry, register_external
from pypy.annotation.model import SomeString, SomeInteger, s_ImpossibleValue, \
s_None
from pypy.annotation.listdef import s_list_of_strings
@@ -35,26 +35,23 @@
os_execv.argtypes = [ctypes.c_char_p, ctypes.POINTER(ctypes.c_char_p)]
os_execv.restype = ctypes.c_int
- class ExecvFuncEntry(ExtFuncEntry):
- _about_ = os.execv
- name = "ll_os.ll_os_execv"
- signature_args = [SomeString(), s_list_of_strings]
- signature_result = s_ImpossibleValue
-
- def lltypeimpl(path, args):
- # XXX incredible code to work around rctypes limitations
- length = len(args) + 1
- num_bytes = ctypes.sizeof(ctypes.c_char_p) * length
- buffer = ctypes.create_string_buffer(num_bytes)
- array = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_char_p))
- buffer_addr = ctypes.cast(buffer, ctypes.c_void_p).value
- for num in range(len(args)):
- adr1 = buffer_addr + ctypes.sizeof(ctypes.c_char_p) * num
- ptr = ctypes.c_void_p(adr1)
- arrayitem = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_char_p))
- arrayitem[0] = args[num]
- os_execv(path, array)
- raise OSError(geterrno(), "execv failed")
+ def execv_lltypeimpl(path, args):
+ # XXX incredible code to work around rctypes limitations
+ length = len(args) + 1
+ num_bytes = ctypes.sizeof(ctypes.c_char_p) * length
+ buffer = ctypes.create_string_buffer(num_bytes)
+ array = ctypes.cast(buffer, ctypes.POINTER(ctypes.c_char_p))
+ buffer_addr = ctypes.cast(buffer, ctypes.c_void_p).value
+ for num in range(len(args)):
+ adr1 = buffer_addr + ctypes.sizeof(ctypes.c_char_p) * num
+ ptr = ctypes.c_void_p(adr1)
+ arrayitem = ctypes.cast(ptr, ctypes.POINTER(ctypes.c_char_p))
+ arrayitem[0] = args[num]
+ os_execv(path, array)
+ raise OSError(geterrno(), "execv failed")
+
+ register_external(os.execv, [str, [str]], s_ImpossibleValue, llimpl=
+ execv_lltypeimpl, export_name="ll_os.ll_os_execv")
os_dup = libc.dup
os_dup.argtypes = [ctypes.c_int]
From cfbolz at codespeak.net Fri Jan 12 19:40:33 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Fri, 12 Jan 2007 19:40:33 +0100 (CET)
Subject: [pypy-svn] r36613 - in pypy/dist/pypy/rpython/module: . test
Message-ID: <20070112184033.C06EB10087@code0.codespeak.net>
Author: cfbolz
Date: Fri Jan 12 19:40:18 2007
New Revision: 36613
Modified:
pypy/dist/pypy/rpython/module/ll_os.py
pypy/dist/pypy/rpython/module/test/test_ll_os.py
pypy/dist/pypy/rpython/module/test/test_posix.py
Log:
adapt dup and dup2 to the new new style and fix the tests
Modified: pypy/dist/pypy/rpython/module/ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/ll_os.py Fri Jan 12 19:40:18 2007
@@ -57,32 +57,24 @@
os_dup.argtypes = [ctypes.c_int]
os_dup.restype = ctypes.c_int
-class DupFuncEntry(ExtFuncEntry):
- _about_ = os.dup
- name = "ll_os.ll_os_dup"
- signature_args = [SomeInteger()]
- signature_result = SomeInteger()
-
- def lltypeimpl(fd):
- newfd = os_dup(fd)
- if newfd == -1:
- raise OSError(geterrno(), "dup failed")
- return newfd
+def dup_lltypeimpl(fd):
+ newfd = os_dup(fd)
+ if newfd == -1:
+ raise OSError(geterrno(), "dup failed")
+ return newfd
+register_external(os.dup, [int], int, llimpl=dup_lltypeimpl,
+ export_name="ll_os.ll_os_dup")
os_dup2 = libc.dup2
os_dup2.argtypes = [ctypes.c_int, ctypes.c_int]
os_dup2.restype = ctypes.c_int
-class Dup2FuncEntry(ExtFuncEntry):
- _about_ = os.dup2
- name = "ll_os.ll_os_dup2"
- signature_args = [SomeInteger(), SomeInteger()]
- signature_result = s_None
-
- def lltypeimpl(fd, newfd):
- error = os_dup2(fd, newfd)
- if error == -1:
- raise OSError(geterrno(), "dup2 failed")
+def dup2_lltypeimpl(fd, newfd):
+ error = os_dup2(fd, newfd)
+ if error == -1:
+ raise OSError(geterrno(), "dup2 failed")
+register_external(os.dup2, [int, int], s_None, llimpl=dup2_lltypeimpl,
+ export_name="ll_os.ll_os_dup2")
class BaseOS:
__metaclass__ = ClassMethods
Modified: pypy/dist/pypy/rpython/module/test/test_ll_os.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_ll_os.py (original)
+++ pypy/dist/pypy/rpython/module/test/test_ll_os.py Fri Jan 12 19:40:18 2007
@@ -131,3 +131,19 @@
else:
os.waitpid(pid, 0)
assert open(filename).read() == "1"
+
+def test_dup():
+ from pypy.rpython.extregistry import lookup
+ os_dup = lookup(os.dup).lltypeimpl.im_func
+ testf = udir.join('test.txt')
+ testf.write("foo")
+ path = testf.strpath
+
+ def ff(fi):
+ g = os_dup(fi)
+ return g
+ fi = os.open(path,os.O_RDONLY,0755)
+ g = ff(fi)
+ assert os.fstat(g) == os.fstat(fi)
+
+
Modified: pypy/dist/pypy/rpython/module/test/test_posix.py
==============================================================================
--- pypy/dist/pypy/rpython/module/test/test_posix.py (original)
+++ pypy/dist/pypy/rpython/module/test/test_posix.py Fri Jan 12 19:40:18 2007
@@ -22,14 +22,6 @@
func = self.interpret(f,[])
assert type(func) == int
- def test_dup(self):
- def ff(fi):
- g = posix.dup(fi)
- return g
- fi = os.open(path,os.O_RDONLY,0755)
- g = self.interpret(ff,[fi])
- assert os.fstat(g) == os.fstat(fi)
-
def test_fstat(self):
def fo(fi):
g = posix.fstat(fi)
From fijal at codespeak.net Fri Jan 12 19:51:06 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 19:51:06 +0100 (CET)
Subject: [pypy-svn] r36614 - pypy/dist/pypy/annotation
Message-ID: <20070112185106.5F1A91007D@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 19:50:55 2007
New Revision: 36614
Modified:
pypy/dist/pypy/annotation/signature.py
Log:
(samuele, fijal) - Fix the SomeList instance to work in more cases.
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Fri Jan 12 19:50:55 2007
@@ -26,8 +26,7 @@
objects of type t."""
if isinstance(t, list):
assert len(t) == 1, "We do not support type joining in list"
- listdef = ListDef(None, annotation(t[0]))
- listdef.listitem.dont_change_any_more = False
+ listdef = ListDef(None, annotation(t[0]), mutated=True, resized=True)
return SomeList(listdef)
elif isinstance(t, tuple):
return SomeTuple(tuple([annotation(i) for i in t]))
From mwh at codespeak.net Fri Jan 12 20:11:12 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Fri, 12 Jan 2007 20:11:12 +0100 (CET)
Subject: [pypy-svn] r36615 - in pypy/dist/pypy/jit/codegen: ppc ppc/test test
Message-ID: <20070112191112.5DD8710083@code0.codespeak.net>
Author: mwh
Date: Fri Jan 12 20:10:37 2007
New Revision: 36615
Modified:
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/regalloc.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
(niko, mwh)
more headbanging on ppc code generation, with tests.
all bugs found by the test_timeshift test test_residual_red_call_with_exc,
which is quite impressive.
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Fri Jan 12 20:10:37 2007
@@ -57,6 +57,9 @@
def move_to_gpr(self, allocator, gpr):
bit, negated = allocator.crfinfo[self.number]
return _CRF2GPR(gpr, self.number*4 + bit, negated)
+ def move_from_gpr(self, allocator, gpr):
+ allocator.crfinfo[self.number] = (2, 1) # cmp2info['ne']
+ return _GPR2CRF(self, gpr)
crfs = map(CRF, range(8))
@@ -169,6 +172,24 @@
self.result_reg.number,
self.imm.value)
+class MoveCRB2GPR(Insn):
+ def __init__(self, result, gv_condition):
+ Insn.__init__(self)
+ self.result = result
+ self.result_regclass = GP_REGISTER
+ self.reg_args = [gv_condition]
+ self.reg_arg_regclasses = [CR_FIELD]
+ def allocate(self, allocator):
+ self.targetreg = allocator.loc_of(self.result)
+ self.crf = allocator.loc_of(self.reg_args[0])
+ self.bit, self.negated = allocator.crfinfo[self.crf.number]
+ assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
+ def emit(self, asm):
+ asm.mfcr(self.targetreg.number)
+ asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+self.bit)
+ if self.negated:
+ asm.xori(self.targetreg.number, self.targetreg.number, 1)
+
class Insn_None__GPR_GPR_IMM(Insn):
def __init__(self, methptr, args):
Insn.__init__(self)
@@ -296,11 +317,13 @@
def allocate(self, allocator):
self.crf = allocator.loc_of(self.reg_args[0])
self.bit, self.negated = allocator.crfinfo[self.crf.number]
+ assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
assert self.targetbuilder.initial_var2loc is None
self.targetbuilder.initial_var2loc = {}
for gv_arg in self.jump_args_gv:
self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
+ self.targetbuilder.initial_crfinfo = allocator.crfinfo[:]
allocator.builders_to_tell_spill_offset_to.append(self.targetbuilder)
def emit(self, asm):
if self.targetbuilder.start:
@@ -457,6 +480,14 @@
if self.negated:
asm.xori(self.targetreg, self.targetreg, 1)
+class _GPR2CRF(AllocTimeInsn):
+ def __init__(self, targetreg, fromreg):
+ AllocTimeInsn.__init__(self)
+ self.targetreg = targetreg
+ self.fromreg = fromreg
+ def emit(self, asm):
+ asm.cmpwi(self.targetreg.number, self.fromreg, 0)
+
class _GPR2CTR(AllocTimeInsn):
def __init__(self, fromreg):
AllocTimeInsn.__init__(self)
Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/regalloc.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py Fri Jan 12 20:10:37 2007
@@ -9,7 +9,8 @@
DEBUG_PRINT = option.debug_print
class RegisterAllocation:
- def __init__(self, freeregs, initial_mapping, initial_spill_offset):
+ def __init__(self, freeregs, initial_mapping,
+ initial_spill_offset, initial_crfinfo):
if DEBUG_PRINT:
print
print "RegisterAllocation __init__", initial_mapping.items()
@@ -39,7 +40,7 @@
# crfinfo is a bit of a hack used to transmit which bit a compare
# instruction set to the branch instruction
- self.crfinfo = [(0, 0)] * 8
+ self.crfinfo = initial_crfinfo[:]
self.builders_to_tell_spill_offset_to = []
def set(self, var, loc):
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Fri Jan 12 20:10:37 2007
@@ -104,15 +104,21 @@
class JumpPatchupGenerator(object):
- def __init__(self, insns, min_offset):
+ def __init__(self, insns, min_offset, allocator):
self.insns = insns
self.min_offset = min_offset
+ self.allocator = allocator
def emit_move(self, tarloc, srcloc):
if tarloc == srcloc: return
emit = self.insns.append
if tarloc.is_register and srcloc.is_register:
- emit(insn.Move(tarloc, srcloc))
+ assert isinstance(tarloc, insn.GPR)
+ if isinstance(srcloc, insn.GPR):
+ emit(insn.Move(tarloc, srcloc))
+ else:
+ assert isinstance(srcloc, insn.CRF)
+ emit(srcloc.move_to_gpr(self.allocator, tarloc.number))
elif tarloc.is_register and not srcloc.is_register:
emit(insn.Unspill(None, tarloc, srcloc))
#self.asm.lwz(tarloc.number, rFP, srcloc.offset)
@@ -130,7 +136,7 @@
self.min_offset -= 4
return insn.stack_slot(r)
-def prepare_for_jump(insns, min_offset, sourcevars, src2loc, target):
+def prepare_for_jump(insns, min_offset, sourcevars, src2loc, target, allocator):
tar2src = {} # tar var -> src var
tar2loc = {}
@@ -147,7 +153,7 @@
else:
insns.append(insn.Load(tloc, src))
- gen = JumpPatchupGenerator(insns, min_offset)
+ gen = JumpPatchupGenerator(insns, min_offset, allocator)
emit_moves(gen, tar2src, tar2loc, src2loc)
return gen.min_offset
@@ -198,6 +204,7 @@
self.stack_adj_addr = 0
self.initial_spill_offset = 0
self.initial_var2loc = None
+ self.initial_crfinfo = [(-1, -1)] * 8
self.max_param_space = -1
self.final_jump_addr = 0
@@ -340,7 +347,29 @@
vars_gv = [v for v in args_gv if isinstance(v, Var)]
#print 'initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
#print 'initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
- var2loc = self.allocate_and_emit(vars_gv).var2loc
+ allocator = self.allocate_and_emit(vars_gv)
+ self.initial_crfinfo = allocator.crfinfo
+ var2loc = allocator.var2loc
+
+ #print '!!!!', args_gv, var2loc
+
+ self.insns = []
+
+ reallocate = False
+ for i in range(len(args_gv)):
+ v = args_gv[i]
+ if isinstance(v, Var) and isinstance(var2loc[v], insn.CRF):
+ reallocate = True
+ nv = Var()
+ self.insns.append(insn.MoveCRB2GPR(nv, v))
+ args_gv[i] = nv
+ self.initial_var2loc = var2loc
+ if reallocate:
+ allocator = self.allocate_and_emit([v for v in args_gv if isinstance(v, Var)])
+ self.initial_crfinfo = allocator.crfinfo
+ var2loc = allocator.var2loc
+ self.insns = []
+
#print 'var2loc.keys():', [id(v) for v in var2loc.keys()]
#print 'var2loc.values():', [id(v) for v in var2loc.values()]
#print 'args_gv', [id(v) for v in args_gv]
@@ -385,7 +414,6 @@
#print livevar2loc
- self.insns = []
self.initial_var2loc = livevar2loc
#print 'final initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
#print 'final initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
@@ -427,7 +455,7 @@
allocator = self.allocate(outputargs_gv)
min_offset = min(allocator.spill_offset, target.min_stack_offset)
allocator.spill_offset = prepare_for_jump(
- self.insns, min_offset, outputargs_gv, allocator.var2loc, target)
+ self.insns, min_offset, outputargs_gv, allocator.var2loc, target, allocator)
self.emit(allocator)
self.asm.load_word(rSCRATCH, target.startaddr)
self.asm.mtctr(rSCRATCH)
@@ -575,7 +603,8 @@
allocator = RegisterAllocation(
self.rgenop.freeregs,
self.initial_var2loc,
- self.initial_spill_offset)
+ self.initial_spill_offset,
+ self.initial_crfinfo)
self.insns = allocator.allocate_for_insns(self.insns)
return allocator
Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Fri Jan 12 20:10:37 2007
@@ -102,9 +102,6 @@
res = fnptr(2)
assert res == 101010
- def test_longwinded_and_direct(self):
- py.test.skip("failing right now")
-
class TestRPPCGenopNoRegs(TestRPPCGenop):
RGenOp = FewRegisters
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Fri Jan 12 20:10:37 2007
@@ -405,6 +405,28 @@
return gv_f
+def make_condition_result_cross_link(rgenop):
+
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "foo")
+
+ gv_result = builder.genop2("int_eq", gv_y, rgenop.genconst(0))
+ target1 = builder.jump_if_false(gv_result, [gv_result])
+
+ builder.finish_and_return(sigtoken, rgenop.genconst(1))
+
+ target1.start_writing()
+ target2 = target1.jump_if_false(gv_result, [])
+
+ # this return should be unreachable:
+ target1.finish_and_return(sigtoken, rgenop.genconst(2))
+
+ target2.start_writing()
+ target2.finish_and_return(sigtoken, rgenop.genconst(3))
+
+ return gv_f
+
class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
RGenOp = None
@@ -609,6 +631,8 @@
gv_fn = make_longwinded_and(rgenop)
fnptr = self.cast(gv_fn, 1)
+ print map(fnptr, range(6))
+
res = fnptr(1)
assert res == 0
@@ -623,3 +647,17 @@
res = fnptr(5)
assert res == 0
+
+ def test_condition_result_cross_link_direct(self):
+ rgenop = self.RGenOp()
+ gv_fn = make_condition_result_cross_link(rgenop)
+ fnptr = self.cast(gv_fn, 1)
+
+ res = fnptr(-1)
+ assert res == 3
+
+ res = fnptr(0)
+ assert res == 1
+
+ res = fnptr(1)
+ assert res == 3
From fijal at codespeak.net Fri Jan 12 20:12:47 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 20:12:47 +0100 (CET)
Subject: [pypy-svn] r36616 - pypy/dist/pypy/annotation
Message-ID: <20070112191247.DCC1F10088@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 20:12:30 2007
New Revision: 36616
Modified:
pypy/dist/pypy/annotation/signature.py
Log:
Argh. Didn't meant to totally break everything at all.
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Fri Jan 12 20:12:30 2007
@@ -84,7 +84,6 @@
assert isinstance(s_input, annmodel.SomePBC)
assert s_input.is_constant()
args_s.append(s_input)
- args_s.append(annmodel.lltype_to_annotation(argtype))
else:
args_s.append(annotation(argtype, bookkeeper=funcdesc.bookkeeper))
if len(inputcells) != len(args_s):
From fijal at codespeak.net Fri Jan 12 20:35:46 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 20:35:46 +0100 (CET)
Subject: [pypy-svn] r36617 - pypy/dist/pypy/module/posix/test
Message-ID: <20070112193546.24DD01007D@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 20:35:30 2007
New Revision: 36617
Modified:
pypy/dist/pypy/module/posix/test/test_posix2.py
Log:
Skip broken test
Modified: pypy/dist/pypy/module/posix/test/test_posix2.py
==============================================================================
--- pypy/dist/pypy/module/posix/test/test_posix2.py (original)
+++ pypy/dist/pypy/module/posix/test/test_posix2.py Fri Jan 12 20:35:30 2007
@@ -127,6 +127,7 @@
raises(OSError, 'os.execv("saddsadsadsadsa", ["saddsadsasaddsa"])')
def test_execve(self):
+ skip("not implemented")
os = self.posix
pid = os.fork()
if pid == 0:
From fijal at codespeak.net Fri Jan 12 20:50:08 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 20:50:08 +0100 (CET)
Subject: [pypy-svn] r36618 - pypy/branch/extfunc-cleanup
Message-ID: <20070112195008.07BE410034@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 20:49:45 2007
New Revision: 36618
Removed:
pypy/branch/extfunc-cleanup/
Log:
Kill dead branch
From antocuni at codespeak.net Fri Jan 12 21:14:55 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 21:14:55 +0100 (CET)
Subject: [pypy-svn] r36619 - in pypy/dist/pypy/rpython/ootypesystem: . test
Message-ID: <20070112201455.891B610082@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 21:14:46 2007
New Revision: 36619
Modified:
pypy/dist/pypy/rpython/ootypesystem/ootype.py
pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
Log:
Make ootype.Instance record its subclasses. This feature will be used
by the check_virtual_methods backend optimization.
Modified: pypy/dist/pypy/rpython/ootypesystem/ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/ootype.py Fri Jan 12 21:14:46 2007
@@ -46,12 +46,14 @@
_is_root=False, _hints = {}):
self._name = name
self._hints = frozendict(_hints)
+ self._subclasses = []
if _is_root:
self._superclass = None
else:
assert isinstance(superclass, Instance)
self._superclass = superclass
+ self._superclass._add_subclass(self)
self._methods = frozendict()
self._fields = frozendict()
@@ -82,6 +84,10 @@
def __str__(self):
return '%s(%s)' % (self.__class__.__name__, self._name)
+ def _add_subclass(self, INSTANCE):
+ assert isinstance(INSTANCE, Instance)
+ self._subclasses.append(INSTANCE)
+
def _add_fields(self, fields):
fields = fields.copy() # mutated below
for name, defn in fields.iteritems():
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_ootype.py Fri Jan 12 21:14:46 2007
@@ -423,3 +423,15 @@
# Instance compares by reference
assert not A == B
assert A != B
+
+def test_subclasses():
+ A = Instance("A", ROOT)
+ B = Instance("B", A)
+ C = Instance("C", A)
+ D = Instance("D", C)
+
+ assert A in ROOT._subclasses
+ assert B in A._subclasses
+ assert not B._subclasses
+ assert C in A._subclasses
+ assert D in C._subclasses
From antocuni at codespeak.net Fri Jan 12 21:18:13 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 21:18:13 +0100 (CET)
Subject: [pypy-svn] r36620 - pypy/dist/pypy/translator
Message-ID: <20070112201813.1214110083@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 21:18:09 2007
New Revision: 36620
Modified:
pypy/dist/pypy/translator/driver.py
Log:
enable some backend optimizations for jvm backend.
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Fri Jan 12 21:18:09 2007
@@ -358,6 +358,10 @@
opt['merge_if_blocks'] = True
opt['inline_threshold'] = 1
opt['mallocs'] = True
+
+ if self.config.translation.backend == 'jvm':
+ opt['inline_threshold'] = 1
+ opt['mallocs'] = True
backend_optimizations(self.translator, **opt)
#
task_backendopt_ootype = taskdef(task_backendopt_ootype,
From antocuni at codespeak.net Fri Jan 12 21:21:56 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 21:21:56 +0100 (CET)
Subject: [pypy-svn] r36621 - in pypy/dist/pypy/translator: . backendopt
backendopt/test cli
Message-ID: <20070112202156.F19481007C@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 21:21:49 2007
New Revision: 36621
Added:
pypy/dist/pypy/translator/backendopt/checkvirtual.py (contents, props changed)
pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py (contents, props changed)
Modified:
pypy/dist/pypy/translator/cli/cts.py
pypy/dist/pypy/translator/driver.py
Log:
the check_virtual_method backendopt allow backends to statically
dispatch some oosends that else would be dispatched at runtime. It
gives about 15% speedup on gencli.
Added: pypy/dist/pypy/translator/backendopt/checkvirtual.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/checkvirtual.py Fri Jan 12 21:21:49 2007
@@ -0,0 +1,19 @@
+"""
+Visit all known INSTANCEs to see which methods can be marked as
+non-virtual: a method is marked as non-virtual when it's never
+overridden in the subclasses: this means that backends can translate
+oosends relative to that method into non-virtual call (or maybe
+switching back to a direct_call if the backend doesn't support
+non-virtual calls, such as JVM).
+"""
+
+def check_virtual_methods(INSTANCE, super_methods = {}):
+ my_methods = super_methods.copy()
+ for name, method in INSTANCE._methods.iteritems():
+ method._virtual = False
+ my_methods[name] = method
+ if name in super_methods:
+ super_methods[name]._virtual = True
+
+ for SUB_INSTANCE in INSTANCE._subclasses:
+ check_virtual_methods(SUB_INSTANCE, my_methods)
Added: pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py Fri Jan 12 21:21:49 2007
@@ -0,0 +1,57 @@
+from pypy.rpython.ootypesystem.ootype import ROOT, Instance, \
+ addMethods, meth, Meth, Void
+from pypy.translator.backendopt.checkvirtual import check_virtual_methods
+
+def test_nonvirtual():
+ A = Instance("A", ROOT)
+ addMethods(A, {"foo": meth(Meth([], Void))})
+
+ check_virtual_methods(ROOT)
+ assert A._methods["foo"]._virtual == False
+
+def test_checkvirtual_simple():
+ A = Instance("A", ROOT)
+ B = Instance("B", A)
+
+ addMethods(A, {"foo": meth(Meth([], Void)),
+ "bar": meth(Meth([], Void))})
+
+ addMethods(B, {"foo": meth(Meth([], Void))})
+
+ check_virtual_methods(ROOT)
+ assert A._methods["foo"]._virtual == True
+ assert A._methods["bar"]._virtual == False
+ assert B._methods["foo"]._virtual == False
+
+def test_checkvirtual_deep():
+ A = Instance("A", ROOT)
+ B = Instance("B", A)
+ C = Instance("C", B)
+
+ addMethods(A, {"foo": meth(Meth([], Void)),
+ "bar": meth(Meth([], Void))})
+
+ addMethods(C, {"foo": meth(Meth([], Void))})
+
+ check_virtual_methods(ROOT)
+ assert A._methods["foo"]._virtual == True
+ assert A._methods["bar"]._virtual == False
+ assert "foo" not in B._methods
+ assert C._methods["foo"]._virtual == False
+
+def test_checkvirtual_brother():
+ A = Instance("A", ROOT)
+ B1 = Instance("B1", A)
+ B2 = Instance("B2", A)
+
+ addMethods(A, {"foo": meth(Meth([], Void)),
+ "bar": meth(Meth([], Void))})
+
+ addMethods(B1, {"foo": meth(Meth([], Void))})
+
+ check_virtual_methods(ROOT)
+ assert A._methods["foo"]._virtual == True
+ assert A._methods["bar"]._virtual == False
+ assert B1._methods["foo"]._virtual == False
+ assert "foo" not in B2._methods
+
Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py (original)
+++ pypy/dist/pypy/translator/cli/cts.py Fri Jan 12 21:21:49 2007
@@ -227,16 +227,18 @@
if isinstance(name_or_desc, ootype._overloaded_meth_desc):
name = name_or_desc.name
METH = name_or_desc.TYPE
+ virtual = True
else:
name = name_or_desc
owner, meth = TYPE._lookup(name)
METH = meth._TYPE
+ virtual = getattr(meth, '_virtual', True)
class_name = self.db.class_name(TYPE)
full_name = 'class %s::%s' % (class_name, name)
returntype = self.lltype_to_cts(METH.RESULT)
arg_types = [self.lltype_to_cts(ARG) for ARG in METH.ARGS if ARG is not ootype.Void]
arg_list = ', '.join(arg_types)
- return '%s %s(%s)' % (returntype, full_name, arg_list), True
+ return '%s %s(%s)' % (returntype, full_name, arg_list), virtual
elif isinstance(TYPE, (ootype.BuiltinType, ootype.StaticMethod)):
assert isinstance(name_or_desc, str)
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Fri Jan 12 21:21:49 2007
@@ -355,6 +355,9 @@
heap2stack=False,
clever_malloc_removal=False)
if self.config.translation.backend == 'cli':
+ from pypy.translator.backendopt.checkvirtual import check_virtual_methods
+ from pypy.rpython.ootypesystem import ootype
+ check_virtual_methods(ootype.ROOT)
opt['merge_if_blocks'] = True
opt['inline_threshold'] = 1
opt['mallocs'] = True
From antocuni at codespeak.net Fri Jan 12 21:24:57 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Fri, 12 Jan 2007 21:24:57 +0100 (CET)
Subject: [pypy-svn] r36622 - pypy/dist/pypy/translator/jvm/test
Message-ID: <20070112202457.C8B4B1007C@code0.codespeak.net>
Author: antocuni
Date: Fri Jan 12 21:24:53 2007
New Revision: 36622
Modified:
pypy/dist/pypy/translator/jvm/test/test_dict.py
Log:
skip this test for now
Modified: pypy/dist/pypy/translator/jvm/test/test_dict.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/test/test_dict.py (original)
+++ pypy/dist/pypy/translator/jvm/test/test_dict.py Fri Jan 12 21:24:53 2007
@@ -17,6 +17,5 @@
py.test.skip("Iteration over empty dict is not supported, yet")
class TestJvmConstantDict(JvmTest, oodict.BaseTestConstantDict):
- pass
-
-
+ def test_constant_r_dict(self):
+ py.test.skip("JVM doesn't support r_dict so far")
From simonb at codespeak.net Fri Jan 12 22:24:17 2007
From: simonb at codespeak.net (simonb at codespeak.net)
Date: Fri, 12 Jan 2007 22:24:17 +0100 (CET)
Subject: [pypy-svn] r36623 - pypy/dist/pypy/doc
Message-ID: <20070112212417.C7BE71007D@code0.codespeak.net>
Author: simonb
Date: Fri Jan 12 22:20:25 2007
New Revision: 36623
Added:
pypy/dist/pypy/doc/standalone-howto.txt
Log:
rough guide to creating standalone executables with rpython
Added: pypy/dist/pypy/doc/standalone-howto.txt
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/doc/standalone-howto.txt Fri Jan 12 22:20:25 2007
@@ -0,0 +1,125 @@
+========================================================
+HOWTO: compile RPython code into a standalone executable
+========================================================
+
+First, see this Disclaimer_ in the FAQ.
+Next, understand the restrictions on RPython_ code.
+Pay close attention to the description of tuples and
+dicts.
+
+Take this example program::
+
+ import os
+
+ def main(argv):
+ os.write(1, "Hello world!\n")
+
+ return 0
+
+To compile::
+
+ from pypy.translator.interactive import Translation
+ t = Translation(main, standalone=True, gc='ref')
+
+ t.source(backend='c')
+ path = t.compile()
+ print path
+
+The path is the location of the executable.
+
+To see the translation in motion, try removing
+the ``argv`` argument to main, or the ``return 0``.
+
+Type inference happens in the Annotator_.
+Keep this in mind as you write RPython code.
+After annotation the low level code generation
+(the implementation of the types)
+happens in the RTyper_.
+
+These steps can be spelled out explicitly::
+
+ t.annotate()
+ t.rtype()
+ t.source(backend='c')
+ path = t.compile()
+
+After the ``annotate()`` or ``rtype()`` call
+you can view the resulting flow graph with
+a pygame/dot based graphing tool::
+
+ t.annotate()
+ t.view()
+ t.rtype()
+ t.view()
+
+Here are some debugging tips:
+
+- make sure the program runs before you try and compile it.
+ The semantics of RPython compiled code should be the same as regular python.
+- try assert'ing things in your code, for example ``assert isinstance(num, int)``,
+ this can provide hints to the translation process that can help pinpoint the
+ problem.
+
+RType'ing is tricky!
+
+Take this example::
+
+ def abs(num):
+ if num < 0:
+ num = -num
+ return num
+
+If you want to use this function with
+different argument types (eg. ``int`` and ``float``)
+the translation will fail. In order
+to generate a different function for each argument
+type we need to set an attribute::
+
+ abs._annspecialcase_ = "specialize:argtype(0)"
+
+As another example::
+
+ def sum(l):
+ total = 0
+ for v in l:
+ total += v
+ return total
+
+ sum._annspecialcase_ = "specialize:argtype(0)"
+
+Note that
+if you use a function like this with a
+*tuple* argument, each tuple of distinct length is considered to
+be a unique type: PyPy will compile (specialize)
+a different ``sum`` function for each different length.
+
+Here is an example of using rctypes_::
+
+ import ctypes
+ from ctypes import c_int, c_char_p
+ import pypy.rpython.rctypes.implementation
+
+ libc = ctypes.cdll.LoadLibrary('libc.so.6')
+
+ write = libc.write
+ write.argtypes = [c_int, c_char_p, c_int]
+ write.restype = c_int
+
+ def main(argv):
+
+ msg = "Hello world!\n"
+ write(1, msg, len(msg))
+
+ return 0
+
+PyPy implements the `ctypes semantics`_ as the corresponding native c-code
+equivalents.
+
+
+.. _`Disclaimer`: faq.html#id10
+.. _`RPython`: coding-guide.html#restricted-python
+.. _`Annotator`: dynamic-language-translation.html#annotator
+.. _`RTyper`: dynamic-language-translation.html#rtyper
+.. _`rctypes`: rctypes.html
+.. _`ctypes semantics`: http://docs.python.org/dev/lib/module-ctypes.html
+
From simonb at codespeak.net Fri Jan 12 22:32:47 2007
From: simonb at codespeak.net (simonb at codespeak.net)
Date: Fri, 12 Jan 2007 22:32:47 +0100 (CET)
Subject: [pypy-svn] r36624 - pypy/dist/pypy/doc
Message-ID: <20070112213247.3F5A01007D@code0.codespeak.net>
Author: simonb
Date: Fri Jan 12 22:32:24 2007
New Revision: 36624
Modified:
pypy/dist/pypy/doc/standalone-howto.txt
Log:
standalone-howto: fix ref
Modified: pypy/dist/pypy/doc/standalone-howto.txt
==============================================================================
--- pypy/dist/pypy/doc/standalone-howto.txt (original)
+++ pypy/dist/pypy/doc/standalone-howto.txt Fri Jan 12 22:32:24 2007
@@ -116,7 +116,7 @@
equivalents.
-.. _`Disclaimer`: faq.html#id10
+.. _`Disclaimer`: faq.html#why-isn-t-there-a-simpler-way-of-doing-that
.. _`RPython`: coding-guide.html#restricted-python
.. _`Annotator`: dynamic-language-translation.html#annotator
.. _`RTyper`: dynamic-language-translation.html#rtyper
From simonb at codespeak.net Fri Jan 12 22:42:26 2007
From: simonb at codespeak.net (simonb at codespeak.net)
Date: Fri, 12 Jan 2007 22:42:26 +0100 (CET)
Subject: [pypy-svn] r36625 - pypy/dist/pypy/doc
Message-ID: <20070112214226.557E01007D@code0.codespeak.net>
Author: simonb
Date: Fri Jan 12 22:41:25 2007
New Revision: 36625
Modified:
pypy/dist/pypy/doc/standalone-howto.txt
Log:
standalone-howto: fix broken paragraph
Modified: pypy/dist/pypy/doc/standalone-howto.txt
==============================================================================
--- pypy/dist/pypy/doc/standalone-howto.txt (original)
+++ pypy/dist/pypy/doc/standalone-howto.txt Fri Jan 12 22:41:25 2007
@@ -60,7 +60,7 @@
this can provide hints to the translation process that can help pinpoint the
problem.
-RType'ing is tricky!
+RPython is tricky!
Take this example::
@@ -87,11 +87,8 @@
sum._annspecialcase_ = "specialize:argtype(0)"
-Note that
-if you use a function like this with a
-*tuple* argument, each tuple of distinct length is considered to
-be a unique type: PyPy will compile (specialize)
-a different ``sum`` function for each different length.
+Now we can sum with different kinds of lists, eg.
+``sum([1,2,3])`` and ``sum([1.0,2.0,3.0])``.
Here is an example of using rctypes_::
From fijal at codespeak.net Fri Jan 12 22:45:11 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Fri, 12 Jan 2007 22:45:11 +0100 (CET)
Subject: [pypy-svn] r36626 - in pypy/dist/pypy/translator/js: . test
Message-ID: <20070112214511.492FA10082@code0.codespeak.net>
Author: fijal
Date: Fri Jan 12 22:44:12 2007
New Revision: 36626
Added:
pypy/dist/pypy/translator/js/test/test_rlist.py
pypy/dist/pypy/translator/js/test/test_rpbc.py
Modified:
pypy/dist/pypy/translator/js/database.py
pypy/dist/pypy/translator/js/test/runtest.py
pypy/dist/pypy/translator/js/test/test_rclass.py
Log:
Wack Wack Wack. More and more tests passes now :)
Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py (original)
+++ pypy/dist/pypy/translator/js/database.py Fri Jan 12 22:44:12 2007
@@ -290,7 +290,6 @@
def record_fields(self):
if not self.obj:
return
- import pdb;pdb.set_trace()
INSTANCE = self.obj._TYPE
#while INSTANCE:
for i, (_type, val) in INSTANCE._allfields().items():
@@ -392,11 +391,14 @@
return self.const._str
def init(self, ilasm):
- s = self.const._str
+ if self.const:
+ s = self.const._str
# do some escaping
#s = s.replace("\n", "\\n").replace('"', '\"')
#s = repr(s).replace("\"", "\\\"")
- ilasm.load_str("%s" % repr(s))
+ ilasm.load_str("%s" % repr(s))
+ else:
+ ilasm.load_str("undefined")
def init_fields(self, ilasm, const_var, name):
pass
Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py (original)
+++ pypy/dist/pypy/translator/js/test/runtest.py Fri Jan 12 22:44:12 2007
@@ -131,37 +131,28 @@
else:
try:
res = float(s)
+ if float(int(res)) == res:
+ return int(res)
except ValueError:
res = str(s)
return res
reinterpret = classmethod(reinterpret)
class JsTest(BaseRtypingTest, OORtypeMixin):
- #def __init__(self):
- # self._func = None
- # self._ann = None
- # self._cli_func = None
-
- def _compile(self, fn, args):
- #ann = [lltype_to_annotation(typeOf(x)) for x in args]
- #if self._func is fn and self._ann == ann:
- # return self._cli_func
- #else:
- # self._func = fn
- # self._ann = ann
- # self._cli_func = compile_function(fn, ann)
- # return self._cli_func
+ def _compile(self, _fn, args):
+ argnames = _fn.func_code.co_varnames[:_fn.func_code.co_argcount]
source = py.code.Source("""
def %s():
from pypy.rlib.nonconst import NonConstant
- res = fn(%s)
+ res = _fn(%s)
if isinstance(res, type(None)):
return None
else:
return str(res)"""
- % (fn.func_name, ",".join(["NonConstant(%s)" % i for i in args])))
+ % (_fn.func_name, ",".join(["%s=NonConstant(%s)" % (name,i) for
+ name, i in zip(argnames, args)])))
exec source.compile() in locals()
- return compile_function(locals()[fn.func_name], [])
+ return compile_function(locals()[_fn.func_name], [])
def interpret(self, fn, args):
#def f(args):
@@ -198,15 +189,14 @@
return l
def class_name(self, value):
- return value.class_name.split(".")[-1]
+ return value[:-10].split('_')[-1]
def is_of_instance_type(self, val):
m = re.match("^<.* instance>$", val)
return bool(m)
def read_attr(self, obj, name):
- pass
- #py.test.skip('read_attr not supported on gencli tests')
+ py.test.skip('read_attr not supported on gencli tests')
def check_source_contains(compiled_function, pattern):
import re
Modified: pypy/dist/pypy/translator/js/test/test_rclass.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_rclass.py (original)
+++ pypy/dist/pypy/translator/js/test/test_rclass.py Fri Jan 12 22:44:12 2007
@@ -2,8 +2,6 @@
from pypy.translator.js.test.runtest import JsTest
from pypy.rpython.test.test_exception import BaseTestException
from pypy.rpython.test.test_rclass import BaseTestRclass
-from pypy.rpython.test.test_rlist import BaseTestRlist
-from pypy.rpython.test.test_rpbc import BaseTestRPBC
from pypy.rpython.test.test_rtuple import BaseTestRtuple
from pypy.rpython.test.test_rstr import BaseTestRstr
@@ -64,7 +62,7 @@
return v0, v1, v2
res = self.interpret(f, [])
- assert isinstance(res[0], float)
+ assert isinstance(res[0], int)
def test_hash_preservation(self):
py.test.skip("WIP")
@@ -75,10 +73,6 @@
def test_isinstance(self):
py.test.skip("WIP")
-#class TestJsList(JsTest, BaseTestRlist):
-# def test_insert_bug(self):
-# py.test.skip("in progress")
-##
#class TestJsPBC(JsTest, BaseTestRPBC):
# pass
##
Added: pypy/dist/pypy/translator/js/test/test_rlist.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/test/test_rlist.py Fri Jan 12 22:44:12 2007
@@ -0,0 +1,78 @@
+
+import py
+from pypy.rpython.test.test_rlist import BaseTestRlist
+from pypy.translator.js.test.runtest import JsTest
+
+class TestJsList(JsTest, BaseTestRlist):
+ def test_append(self):
+ def dummyfn():
+ l = []
+ l.append(50)
+ l.append(60)
+ l.append(70)
+ l.append(80)
+ l.append(90)
+ return len(l), l[0], l[-1]
+ res = self.interpret(dummyfn, [])
+ assert res == [5, 50, 90]
+
+ def test_slice(self):
+ py.test.skip("Imperfect testing machinery")
+ def dummyfn():
+ l = [5, 6, 7, 8, 9]
+ return l[:2], l[1:4], l[3:]
+ res = self.interpret(dummyfn, [])
+
+ def dummyfn():
+ l = [5, 6, 7, 8]
+ l.append(9)
+ return l[:2], l[1:4], l[3:]
+ res = self.interpret(dummyfn, [])
+ assert res == ([5, 6], [6, 7, 8], [8, 9])
+
+ def test_setslice(self):
+ def dummyfn():
+ l = [10, 9, 8, 7]
+ l[:2] = [6, 5]
+ return l[0], l[1], l[2], l[3]
+ res = self.interpret(dummyfn, ())
+ assert res == [6, 5, 8, 7]
+
+ def test_insert_bug(self):
+ def dummyfn(n):
+ l = [1]
+ l = l[:]
+ l.pop(0)
+ if n < 0:
+ l.insert(0, 42)
+ else:
+ l.insert(n, 42)
+ return l
+ res = self.interpret(dummyfn, [0])
+ assert len(res) == 1
+ assert res[0] == 42
+ res = self.interpret(dummyfn, [-1])
+ assert len(res) == 1
+ assert res[0] == 42
+
+ def test_list_str(self):
+ pass
+
+ def test_inst_list(self):
+ py.test.skip("WIP")
+ def fn():
+ l = [None]
+ l[0] = Foo()
+ l.append(Bar())
+ l2 = [l[1], l[0], l[0]]
+ l.extend(l2)
+ for x in l2:
+ l.append(x)
+ x = l.pop()
+ x = l.pop()
+ x = l.pop()
+ x = l2.pop()
+ return str(x)+";"+str(l)
+ res = self.ll_to_string(self.interpret(fn, []))
+ res = res.replace('pypy.rpython.test.test_rlist.', '')
+ assert res == ';[, , , , ]'
Added: pypy/dist/pypy/translator/js/test/test_rpbc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/test/test_rpbc.py Fri Jan 12 22:44:12 2007
@@ -0,0 +1,72 @@
+
+import py
+from pypy.translator.js.test.runtest import JsTest
+from pypy.rpython.test.test_rpbc import BaseTestRPBC
+
+class Freezing:
+ def _freeze_(self):
+ return True
+ def mymethod(self, y):
+ return self.x + y
+
+class TestJsPBC(JsTest, BaseTestRPBC):
+
+ def test_call_memoized_function_with_bools(self):
+ py.test.skip("WIP")
+
+ def test_pbc_getattr_conversion_with_classes(self):
+ class base: pass
+ class fr1(base): pass
+ class fr2(base): pass
+ class fr3(base): pass
+ fr1.value = 10
+ fr2.value = 5
+ fr3.value = 2.5
+ def pick12(i):
+ if i > 0:
+ return fr1
+ else:
+ return fr2
+ def pick23(i):
+ if i > 5:
+ return fr2
+ else:
+ return fr3
+ def f(i):
+ x = pick12(i)
+ y = pick23(i)
+ return x.value, y.value
+ for i in [0, 5, 10]:
+ res = self.interpret(f, [i])
+ assert res == list(f(i))
+
+ def test_pbc_getattr_conversion(self):
+ fr1 = Freezing()
+ fr2 = Freezing()
+ fr3 = Freezing()
+ fr1.value = 10
+ fr2.value = 5
+ fr3.value = 2.5
+ def pick12(i):
+ if i > 0:
+ return fr1
+ else:
+ return fr2
+ def pick23(i):
+ if i > 5:
+ return fr2
+ else:
+ return fr3
+ def f(i):
+ x = pick12(i)
+ y = pick23(i)
+ return x.value, y.value
+ for i in [0, 5, 10]:
+ res = self.interpret(f, [i])
+ assert res == list(f(i))
+
+ def test_conv_from_None(self):
+ py.test.skip("WIP")
+
+
+
From ericvrp at codespeak.net Fri Jan 12 22:50:23 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Fri, 12 Jan 2007 22:50:23 +0100 (CET)
Subject: [pypy-svn] r36627 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070112215023.70F4510080@code0.codespeak.net>
Author: ericvrp
Date: Fri Jan 12 22:50:17 2007
New Revision: 36627
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_exception.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py
Log:
more passing tests in jit/codegen/llvm
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Fri Jan 12 22:50:17 2007
@@ -536,11 +536,12 @@
gv_comp = Var(i1)
gv_abs_pos = Var(gv_x.type)
gv_result = Var(gv_x.type)
- if nullstr == '0':
- l = ' %s=' + scmp + 'ge %s,%s'
+ if nullstr == 'null' or nullstr == '0':
+ cmp = scmp
else:
- l = ' %s=' + fcmp + 'ge %s,%s'
- self.asm.append(l % (gv_comp.operand2(), gv_x.operand(), nullstr))
+ cmp = fcmp
+ self.asm.append(' %s=%sge %s,%s' % (
+ gv_comp.operand2(), cmp, gv_x.operand(), nullstr))
self.asm.append(' %s=sub %s %s,%s' % (
gv_abs_pos.operand2(), gv_x.type, nullstr, gv_x.operand2()))
self.asm.append(' %s=select %s,%s,%s' % (
@@ -679,21 +680,23 @@
def _is_false(self, gv_x, nullstr='0'):
log('%s Builder._is_false %s' % (self.block.label, gv_x.operand()))
gv_result = Var(i1)
- if nullstr == '0':
- l = ' %s=' + icmp + 'eq %s,%s'
+ if nullstr == 'null' or nullstr == '0':
+ cmp = icmp
else:
- l = ' %s=' + fcmp + 'eq %s,%s'
- self.asm.append(l % (gv_result.operand2(), gv_x.operand(), nullstr))
+ cmp = fcmp
+ self.asm.append(' %s=%seq %s,%s' % (
+ gv_result.operand2(), cmp, gv_x.operand(), nullstr))
return gv_result
def _is_true(self, gv_x, nullstr='0'):
log('%s Builder._is_true %s' % (self.block.label, gv_x.operand()))
gv_result = Var(i1)
- if nullstr == '0':
- l = ' %s=' + icmp + 'ne %s,%s'
+ if nullstr == 'null' or nullstr == '0':
+ cmp = icmp
else:
- l = ' %s=' + fcmp + 'ne %s,%s'
- self.asm.append(l % (gv_result.operand2(), gv_x.operand(), nullstr))
+ cmp = fcmp
+ self.asm.append(' %s=%sne %s,%s' % (
+ gv_result.operand2(), cmp, gv_x.operand(), nullstr))
return gv_result
op_bool_is_true = op_char_is_true = op_unichar_is_true = op_int_is_true =\
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_exception.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_exception.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_exception.py Fri Jan 12 22:50:17 2007
@@ -2,7 +2,6 @@
from pypy.jit.timeshifter.test import test_exception
from pypy.jit.codegen.llvm.test.test_genc_ts import LLVMTimeshiftingTestMixin
-py.test.skip("WIP")
class TestException(LLVMTimeshiftingTestMixin,
test_exception.TestException):
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Fri Jan 12 22:50:17 2007
@@ -28,9 +28,4 @@
test_green_char_at_merge = skip #segfault
test_residual_red_call_with_exc = skip
else: #needs fixing for >= 2.0
- test_red_array = skip
- test_red_struct_array = skip
- test_red_varsized_struct = skip
test_array_of_voids = skip
- test_merge_structures = skip
- test_green_char_at_merge = skip
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py Fri Jan 12 22:50:17 2007
@@ -3,12 +3,13 @@
from pypy.jit.codegen.llvm.test.test_genc_ts import LLVMTimeshiftingTestMixin
-py.test.skip('WIP')
-
class TestVList(LLVMTimeshiftingTestMixin,
test_vlist.TestVList):
# for the individual tests see
# ====> ../../../timeshifter/test/test_vlist.py
- pass
+ def skip(self):
+ py.test.skip("WIP")
+
+ test_force = skip
From niko at codespeak.net Sat Jan 13 00:10:21 2007
From: niko at codespeak.net (niko at codespeak.net)
Date: Sat, 13 Jan 2007 00:10:21 +0100 (CET)
Subject: [pypy-svn] r36628 - pypy/dist/pypy/jit/codegen/ppc
Message-ID: <20070112231021.0BE351005A@code0.codespeak.net>
Author: niko
Date: Sat Jan 13 00:10:11 2007
New Revision: 36628
Modified:
pypy/dist/pypy/jit/codegen/ppc/instruction.py
pypy/dist/pypy/jit/codegen/ppc/regalloc.py
pypy/dist/pypy/jit/codegen/ppc/rgenop.py
Log:
purge crfinfo, and instead store the information about which
bits etc we need from the condition registers in the CRF object
Modified: pypy/dist/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/instruction.py Sat Jan 13 00:10:11 2007
@@ -6,11 +6,24 @@
rFP = r2 # the ABI doesn't specify a frame pointer. however, we want one
class AllocationSlot(object):
- pass
+ def __init__(self):
+ # The field alloc points to a singleton used by the register
+ # allocator to detect conflicts. No two AllocationSlot
+ # instances with the same value in self.alloc can be used at
+ # once.
+ self.alloc = self
+
+ def make_loc(self):
+ """ When we assign a variable to one of these registers, we
+ call make_loc() to get the actual location instance; that
+ instance will have its alloc field set to self. For
+ everything but condition registers, this is self."""
+ return self
class _StackSlot(AllocationSlot):
is_register = False
def __init__(self, offset):
+ AllocationSlot.__init__(self)
self.offset = offset
def __repr__(self):
return "stack@%s"%(self.offset,)
@@ -34,10 +47,13 @@
class Register(AllocationSlot):
is_register = True
+ def __init__(self):
+ AllocationSlot.__init__(self)
class GPR(Register):
regclass = GP_REGISTER
def __init__(self, number):
+ Register.__init__(self)
self.number = number
def __repr__(self):
return 'r' + str(self.number)
@@ -46,23 +62,47 @@
class FPR(Register):
regclass = FP_REGISTER
def __init__(self, number):
+ Register.__init__(self)
self.number = number
fprs = map(GPR, range(32))
-class CRF(Register):
+class BaseCRF(Register):
+ """ These represent condition registers; however, we never actually
+ use these as the location of something in the register allocator.
+ Instead, we place it in an instance of CRF which indicates which
+ bits are required to extract the value. Note that CRF().alloc will
+ always be an instance of this. """
regclass = CR_FIELD
def __init__(self, number):
self.number = number
+ self.alloc = self
+ def make_loc(self):
+ return CRF(self)
+
+crfs = map(BaseCRF, range(8))
+
+class CRF(Register):
+ regclass = CR_FIELD
+ def __init__(self, crf):
+ Register.__init__(self)
+ self.alloc = crf
+ self.number = crf.number
+ self.info = (-1,-1) # (bit, negated)
+ def set_info(self, info):
+ assert len(info) == 2
+ self.info = info
+ def make_loc(self):
+ # should never call this on a CRF, only a BaseCRF
+ raise NotImplementedError
def move_to_gpr(self, allocator, gpr):
- bit, negated = allocator.crfinfo[self.number]
- return _CRF2GPR(gpr, self.number*4 + bit, negated)
+ bit, negated = self.info
+ return _CRF2GPR(gpr, self.alloc.number*4 + bit, negated)
def move_from_gpr(self, allocator, gpr):
- allocator.crfinfo[self.number] = (2, 1) # cmp2info['ne']
+ # cmp2info['ne']
+ self.set_info((2, 1))
return _GPR2CRF(self, gpr)
-crfs = map(CRF, range(8))
-
class CTR(Register):
regclass = CT_REGISTER
def move_from_gpr(self, allocator, gpr):
@@ -182,12 +222,12 @@
def allocate(self, allocator):
self.targetreg = allocator.loc_of(self.result)
self.crf = allocator.loc_of(self.reg_args[0])
- self.bit, self.negated = allocator.crfinfo[self.crf.number]
- assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
def emit(self, asm):
+ assert isinstance(self.crf, CRF)
+ bit, negated = self.crf.info
asm.mfcr(self.targetreg.number)
- asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+self.bit)
- if self.negated:
+ asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+bit)
+ if negated:
asm.xori(self.targetreg.number, self.targetreg.number, 1)
class Insn_None__GPR_GPR_IMM(Insn):
@@ -235,22 +275,25 @@
self.reg3.number)
class CMPInsn(Insn):
- info = (0,0) # please the annotator for tests that don't use CMPW/CMPWI
- pass
-
-class CMPW(CMPInsn):
- def __init__(self, info, result, args):
+ def __init__(self, info, result):
Insn.__init__(self)
self.info = info
-
self.result = result
- self.result_regclass = CR_FIELD
+ def allocate(self, allocator):
+ self.result_reg = allocator.loc_of(self.result)
+ assert isinstance(self.result_reg, CRF)
+ self.result_reg.set_info(self.info)
+
+class CMPW(CMPInsn):
+ def __init__(self, info, result, args):
+ CMPInsn.__init__(self, info, result)
+ self.result_regclass = CR_FIELD
self.reg_args = args
self.reg_arg_regclasses = [GP_REGISTER, GP_REGISTER]
def allocate(self, allocator):
- self.result_reg = allocator.loc_of(self.result)
+ CMPInsn.allocate(self, allocator)
self.arg_reg1 = allocator.loc_of(self.reg_args[0])
self.arg_reg2 = allocator.loc_of(self.reg_args[1])
@@ -263,18 +306,14 @@
class CMPWI(CMPInsn):
def __init__(self, info, result, args):
- Insn.__init__(self)
- self.info = info
+ CMPInsn.__init__(self, info, result)
self.imm = args[1]
-
- self.result = result
self.result_regclass = CR_FIELD
-
self.reg_args = [args[0]]
self.reg_arg_regclasses = [GP_REGISTER]
def allocate(self, allocator):
- self.result_reg = allocator.loc_of(self.result)
+ CMPInsn.allocate(self, allocator)
self.arg_reg = allocator.loc_of(self.reg_args[0])
def emit(self, asm):
@@ -316,14 +355,11 @@
self.targetbuilder = targetbuilder
def allocate(self, allocator):
self.crf = allocator.loc_of(self.reg_args[0])
- self.bit, self.negated = allocator.crfinfo[self.crf.number]
- assert self.bit != -1 and self.negated != -1, "uninitialized crfinfo!"
assert self.targetbuilder.initial_var2loc is None
self.targetbuilder.initial_var2loc = {}
for gv_arg in self.jump_args_gv:
self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
- self.targetbuilder.initial_crfinfo = allocator.crfinfo[:]
allocator.builders_to_tell_spill_offset_to.append(self.targetbuilder)
def emit(self, asm):
if self.targetbuilder.start:
@@ -332,11 +368,12 @@
self.targetbuilder.patch_start_here = asm.mc.tell()
asm.load_word(rSCRATCH, 0)
asm.mtctr(rSCRATCH)
- if self.negated ^ self.jump_if_true:
+ bit, negated = self.crf.info
+ if negated ^ self.jump_if_true:
BO = 12 # jump if relavent bit is set in the CR
else:
BO = 4 # jump if relavent bit is NOT set in the CR
- asm.bcctr(BO, self.crf.number*4 + self.bit)
+ asm.bcctr(BO, self.crf.number*4 + bit)
class SpillCalleeSaves(Insn):
def __init__(self):
Modified: pypy/dist/pypy/jit/codegen/ppc/regalloc.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/regalloc.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/regalloc.py Sat Jan 13 00:10:11 2007
@@ -9,8 +9,7 @@
DEBUG_PRINT = option.debug_print
class RegisterAllocation:
- def __init__(self, freeregs, initial_mapping,
- initial_spill_offset, initial_crfinfo):
+ def __init__(self, freeregs, initial_mapping, initial_spill_offset):
if DEBUG_PRINT:
print
print "RegisterAllocation __init__", initial_mapping.items()
@@ -34,13 +33,10 @@
# go through the initial mapping and initialize the data structures
for var, loc in initial_mapping.iteritems():
self.set(var, loc)
- if loc.is_register and loc in self.freeregs[loc.regclass]:
- self.freeregs[loc.regclass].remove(loc)
+ if loc.is_register and loc.alloc in self.freeregs[loc.regclass]:
+ self.freeregs[loc.regclass].remove(loc.alloc)
self.lru.append(var)
- # crfinfo is a bit of a hack used to transmit which bit a compare
- # instruction set to the branch instruction
- self.crfinfo = initial_crfinfo[:]
self.builders_to_tell_spill_offset_to = []
def set(self, var, loc):
@@ -79,7 +75,7 @@
freeregs = self.freeregs[regclass]
if freeregs:
- reg = freeregs.pop()
+ reg = freeregs.pop().make_loc()
self.set(newarg, reg)
if DEBUG_PRINT:
print "allocate_reg: Putting %r into fresh register %r" % (newarg, reg)
@@ -105,7 +101,7 @@
print "allocate_reg: Spilled %r to %r." % (argtospill, self.loc_of(argtospill))
# update data structures to put newarg into the register
- self.set(newarg, reg)
+ self.set(newarg, reg.alloc.make_loc())
if DEBUG_PRINT:
print "allocate_reg: Put %r in stolen reg %r." % (newarg, reg)
return reg
@@ -174,7 +170,7 @@
# it's in the wrong kind of register
# (this code is excessively confusing)
self.forget(arg, argloc)
- self.freeregs[argloc.regclass].append(argloc)
+ self.freeregs[argloc.regclass].append(argloc.alloc)
if argloc.regclass != GP_REGISTER:
if argcls == GP_REGISTER:
gpr = self._allocate_reg(GP_REGISTER, arg).number
@@ -199,8 +195,6 @@
if DEBUG_PRINT:
print "Allocating register for result %r..." % (insn.result,)
resultreg = self._allocate_reg(insn.result_regclass, insn.result)
- if isinstance(insn, CMPInsn):
- self.crfinfo[resultreg.number] = insn.info
insn.allocate(self)
self.insns.append(insn)
return self.insns
Modified: pypy/dist/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/rgenop.py Sat Jan 13 00:10:11 2007
@@ -29,6 +29,7 @@
_var_index = [0]
class Var(GenVar):
+ conditional = False
def __init__(self):
self.__magic_index = _var_index[0]
_var_index[0] += 1
@@ -37,11 +38,16 @@
def fits_in_immediate(self):
return False
+class ConditionVar(Var):
+ """ Used for vars that originated as the result of a conditional
+ operation, like a == b """
+ conditional = True
+
class IntConst(GenConst):
def __init__(self, value):
self.value = value
-
+
@specialize.arg(1)
def revealconst(self, T):
if isinstance(T, lltype.Ptr):
@@ -204,7 +210,6 @@
self.stack_adj_addr = 0
self.initial_spill_offset = 0
self.initial_var2loc = None
- self.initial_crfinfo = [(-1, -1)] * 8
self.max_param_space = -1
self.final_jump_addr = 0
@@ -348,7 +353,6 @@
#print 'initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
#print 'initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
allocator = self.allocate_and_emit(vars_gv)
- self.initial_crfinfo = allocator.crfinfo
var2loc = allocator.var2loc
#print '!!!!', args_gv, var2loc
@@ -366,7 +370,6 @@
self.initial_var2loc = var2loc
if reallocate:
allocator = self.allocate_and_emit([v for v in args_gv if isinstance(v, Var)])
- self.initial_crfinfo = allocator.crfinfo
var2loc = allocator.var2loc
self.insns = []
@@ -603,8 +606,7 @@
allocator = RegisterAllocation(
self.rgenop.freeregs,
self.initial_var2loc,
- self.initial_spill_offset,
- self.initial_crfinfo)
+ self.initial_spill_offset)
self.insns = allocator.allocate_for_insns(self.insns)
return allocator
@@ -710,7 +712,7 @@
def _compare(self, op, gv_x, gv_y):
#print "op", op
- gv_result = Var()
+ gv_result = ConditionVar()
if gv_y.fits_in_immediate():
self.insns.append(
insn.CMPWI(self.cmp2info[op], gv_result, [gv_x, gv_y]))
@@ -723,7 +725,7 @@
return gv_result
def _compare_u(self, op, gv_x, gv_y):
- gv_result = Var()
+ gv_result = ConditionVar()
if gv_y.fits_in_immediate():
self.insns.append(
insn.CMPWLI(self.cmp2info[op], gv_result, [gv_x, gv_y]))
From arigo at codespeak.net Sat Jan 13 12:06:17 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 12:06:17 +0100 (CET)
Subject: [pypy-svn] r36634 - in pypy/branch/i386-regalloc/pypy/jit/codegen:
i386 test
Message-ID: <20070113110617.B666C1007D@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 12:06:05 2007
New Revision: 36634
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
Small fixes, int_floor_div, int_mul.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 12:06:05 2007
@@ -32,13 +32,13 @@
self.x = x
def allocate(self, allocator):
allocator.using(self.x)
- def generate(self, allocator):
- try:
- loc = allocator.var2loc[self]
- except KeyError:
- return # simple operation whose result is not used anyway
- op = allocator.load_location_with(loc, self.x)
- self.emit(allocator.mc, op)
+## def generate(self, allocator):
+## try:
+## loc = allocator.var2loc[self]
+## except KeyError:
+## return # simple operation whose result is not used anyway
+## op = allocator.load_location_with(loc, self.x)
+## self.emit(allocator.mc, op)
class OpSameAs(Op1):
clobbers_cc = False
@@ -60,14 +60,8 @@
result_kind = RK_CC
def generate(self, allocator):
srcop = allocator.get_operand(self.x)
- dstop = allocator.get_operand(self.y)
mc = allocator.mc
- # XXX optimize the case CMP(immed, reg-or-modrm)
- try:
- mc.CMP(srcop, dstop)
- except FailedToImplement:
- mc.MOV(ecx, srcop)
- mc.CMP(ecx, dstop)
+ self.emit(mc, srcop)
class OpIntIsTrue(OpCompare1):
opname = 'int_is_true'
@@ -92,8 +86,8 @@
op1 = allocator.get_operand(self.x)
op2 = allocator.get_operand(self.y)
# now all of dstop, op1 and op2 may alias each other and be in
- # a register or in the stack... finding a correct and encodable
- # combination of instructions is loads of fun
+ # a register, in the stack or an immediate... finding a correct
+ # and encodable combination of instructions is loads of fun
mc = allocator.mc
if dstop == op1:
case = 1 # optimize for this common case
@@ -112,7 +106,7 @@
case = 2
else:
case = 3
- # this is a separator line but a blank line doesn't look nice here
+ # generate instructions according to the 'case' determined above
if case == 1:
# dstop == op1
try:
@@ -146,6 +140,40 @@
emit = staticmethod(I386CodeBuilder.IMUL)
commutative = True
+class OpIntFloorDiv(Op2):
+ opname = 'int_floordiv'
+ divmod_result_register = eax
+ def generate(self, allocator):
+ try:
+ dstop = allocator.get_operand(self)
+ except KeyError:
+ return # simple operation whose result is not used anyway
+ op1 = allocator.get_operand(self.x)
+ op2 = allocator.get_operand(self.y)
+ # not very efficient but not a very common operation either
+ mc = allocator.mc
+ if dstop != eax:
+ mc.PUSH(eax)
+ if dstop != edx:
+ mc.PUSH(edx)
+ if op1 != eax:
+ mc.MOV(eax, op1)
+ mc.CDQ()
+ try:
+ mc.IDIV(op2)
+ except FailedToImplement:
+ mc.MOV(ecx, op2)
+ mc.IDIV(ecx)
+ mc.MOV(dstop, self.divmod_result_register)
+ if dstop != edx:
+ mc.POP(edx)
+ if dstop != eax:
+ mc.POP(eax)
+
+class OpIntMod(OpIntFloorDiv):
+ opname = 'int_mod'
+ divmod_result_register = edx
+
class OpCompare2(Op2):
result_kind = RK_CC
def generate(self, allocator):
@@ -405,8 +433,15 @@
else:
operand = force_operands[i]
if loc in force_loc2operand or operand in force_operand2loc:
- if not at_start: raise NotImplementedError
- self.initial_moves.append((loc, operand))
+ if at_start:
+ self.initial_moves.append((loc, operand))
+ else:
+ v2 = OpSameAs(v)
+ self.operations.append(v2)
+ loc = self.nextloc
+ self.nextloc += 1
+ self.var2loc[v2] = loc
+ force_loc2operand[loc] = operand
else:
force_loc2operand[loc] = operand
force_operand2loc[operand] = loc
@@ -470,12 +505,13 @@
if last_n >= 0:
self.mc.LEA(esp, stack_op(last_n))
# XXX naive algo for now
- # XXX at least remove moves that don't move anything!
for loc, srcoperand in initial_moves:
- self.mc.PUSH(srcoperand)
+ if self.operands[loc] != srcoperand:
+ self.mc.PUSH(srcoperand)
initial_moves.reverse()
for loc, srcoperand in initial_moves:
- self.mc.POP(self.operands[loc])
+ if self.operands[loc] != srcoperand:
+ self.mc.POP(self.operands[loc])
class Builder(GenBuilder):
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386.py Sat Jan 13 12:06:05 2007
@@ -38,6 +38,7 @@
class IMM32(OPERAND):
width = 4
+ value = 0 # annotator hack
def __init__(self, value):
self.value = value
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 12:06:05 2007
@@ -183,9 +183,9 @@
def make_goto(rgenop):
# z = 1
# while x > 0:
- # y += x
- # z *= x
- # x -= 1
+ # z = x * z
+ # y = x + y
+ # x = x - 1
# y += z
# return y
signed_kind = rgenop.kindToken(lltype.Signed)
@@ -475,7 +475,7 @@
assert res == expected
def test_largedummy_compile(self):
- fn = self.compile(get_largedummy_runner(self.RGenOp), [int, int])
+ fn = self.compile(get_largedummy_runner(self.RGenOp), [int] * 100)
args, expected = largedummy_example()
res = fn(*args)
assert res == expected
From arigo at codespeak.net Sat Jan 13 12:10:16 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 12:10:16 +0100 (CET)
Subject: [pypy-svn] r36635 - in pypy/branch/i386-regalloc/pypy/jit/codegen:
. llgraph llgraph/test llvm llvm/test ppc ppc/test test
Message-ID: <20070113111016.21E8010082@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 12:09:25 2007
New Revision: 36635
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/llimpl.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/test/test_rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/compatibility.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_exception.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_vlist.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_operation.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/model.py
pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/instruction.py
pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/regalloc.py
pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
svn merge -r36412:36633 http://codespeak.net/svn/pypy/dist/pypy/jit/codegen
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/llimpl.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/llimpl.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/llimpl.py Sat Jan 13 12:09:25 2007
@@ -193,7 +193,11 @@
elif T == llmemory.Address:
return llmemory.cast_ptr_to_adr(c.value)
else:
- return lltype.cast_primitive(T, c.value)
+ if lltype.typeOf(c.value) == llmemory.Address:
+ value = llmemory.cast_adr_to_int(c.value)
+ else:
+ value = c.value
+ return lltype.cast_primitive(T, value)
def isconst(gv_value):
c = from_opaque_object(gv_value)
@@ -543,3 +547,35 @@
#setannotation(placeholder, s_ConstOrVar, specialize_as_constant=True)
setannotation(show_incremental_progress, None)
+
+# read frame var support
+
+def read_frame_var(T, base, info, index):
+ vars = info._obj.vars
+ v = vars[index]
+ if isinstance(v, flowmodel.Constant):
+ val = v.value
+ else:
+ llframe = base.ptr
+ val = llframe.bindings[v]
+ assert lltype.typeOf(val) == T
+ return val
+
+
+class ReadFrameVarEntry(ExtRegistryEntry):
+ "Annotation and specialization for calls to 'func'."
+ _about_ = read_frame_var
+
+ def compute_result_annotation(self, *args_s):
+ T = args_s[0].const
+ return annmodel.lltype_to_annotation(T)
+
+ # specialize as direct_call
+ def specialize_call(self, hop):
+ FUNCTYPE = lltype.FuncType([r.lowleveltype for r in hop.args_r],
+ hop.r_result.lowleveltype)
+ args_v = hop.inputargs(*hop.args_r)
+ funcptr = lltype.functionptr(FUNCTYPE, 'read_frame_var',
+ _callable=read_frame_var)
+ cfunc = hop.inputconst(lltype.Ptr(FUNCTYPE), funcptr)
+ return hop.genop('direct_call', [cfunc] + args_v, hop.r_result)
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/rgenop.py Sat Jan 13 12:09:25 2007
@@ -1,5 +1,5 @@
from pypy.rlib.objectmodel import specialize
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.llgraph import llimpl
@@ -39,6 +39,8 @@
gv_Signed = gv_TYPE(lltype.Signed)
gv_dummy_placeholder = LLConst(llimpl.dummy_placeholder)
+gv_Address = gv_TYPE(llmemory.Address)
+gv_GCREF = gv_TYPE(llmemory.GCREF)
class LLLabel(GenLabel):
def __init__(self, b, g):
@@ -220,6 +222,16 @@
llimpl.show_incremental_progress(self.gv_f)
+ # read_frame_var support
+
+ def get_frame_base(self):
+ return LLVar(llimpl.genop(self.b, 'get_frame_base', [],
+ gv_Address.v))
+
+ def get_frame_info(self, vars):
+ return LLVar(llimpl.genop(self.b, 'get_frame_info', vars,
+ gv_GCREF.v))
+
class RGenOp(AbstractRGenOp):
gv_Void = gv_Void
@@ -302,5 +314,10 @@
def _freeze_(self):
return True # no real point in using a full class in llgraph
+ @staticmethod
+ @specialize.arg(0)
+ def read_frame_var(T, base, info, index):
+ return llimpl.read_frame_var(T, base, info, index)
+
rgenop = RGenOp() # no real point in using a full class in llgraph
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/test/test_rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/test/test_rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llgraph/test/test_rgenop.py Sat Jan 13 12:09:25 2007
@@ -1,9 +1,9 @@
import py
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.llgraph.rgenop import RGenOp
from pypy.jit.codegen.llgraph.llimpl import testgengraph
from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests
-from pypy.rpython.test.test_llinterp import interpret
+from pypy.rpython.test.test_llinterp import gengraph, interpret
class TestLLGraphRGenop(AbstractRGenOpTests):
@@ -23,3 +23,35 @@
# for the individual tests see
# ====> ../../test/rgenop_tests.py
+
+
+def test_read_frame_var():
+ from pypy.annotation import model as annmodel
+
+ def reader(base, info):
+ return RGenOp.read_frame_var(lltype.Signed, base, info, 0)
+
+ t, rtyper, reader_graph = gengraph(reader,
+ [annmodel.SomeAddress(),
+ annmodel.SomePtr(llmemory.GCREF)])
+ reader_ptr = rtyper.getcallable(reader_graph)
+
+ F1 = lltype.FuncType([lltype.Signed], lltype.Signed)
+ rgenop = RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(F1)
+ gv_reader = RGenOp.constPrebuiltGlobal(reader_ptr)
+ readertoken = rgenop.sigToken(lltype.typeOf(reader_ptr).TO)
+
+ builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "f")
+
+ gv_y = builder.genop2("int_mul", gv_x, rgenop.genconst(2))
+ gv_base = builder.get_frame_base()
+ gv_info = builder.get_frame_info([gv_y])
+ gv_z = builder.genop_call(readertoken, gv_reader, [gv_base, gv_info])
+ builder.finish_and_return(sigtoken, gv_z)
+ builder.end()
+
+ ptr = gv_f.revealconst(lltype.Ptr(F1))
+ res = testgengraph(ptr._obj.graph, [21])
+ assert res == 42
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/compatibility.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/compatibility.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/compatibility.py Sat Jan 13 12:09:25 2007
@@ -7,7 +7,7 @@
if llvm_version() < 2.0:
icmp = scmp = ucmp = fcmp = 'set'
inttoptr = trunc = zext = bitcast = 'cast'
- shr_prefix = ('', '')
+ shr_prefix = ['', '']
i8 = 'ubyte'
i16 = 'short'
i32 = 'int'
@@ -22,9 +22,12 @@
trunc = 'trunc'
zext = 'zext'
bitcast = 'bitcast'
- shr_prefix = ('l', 'a')
+ shr_prefix = ['l', 'a']
define = 'define'
i8 = 'i8'
i16 = 'i16'
i32 = 'i32'
i64 = 'i64'
+
+i1 = 'bool'
+f64 = 'double'
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py Sat Jan 13 12:09:25 2007
@@ -1,6 +1,7 @@
import py, os
from pypy.rlib.objectmodel import specialize
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rlib.rarithmetic import intmask
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.jit.codegen.llvm import llvmjit
@@ -8,15 +9,17 @@
from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr
from pypy.jit.codegen.llvm.conftest import option
from pypy.jit.codegen.llvm.compatibility import icmp, scmp, ucmp, fcmp, inttoptr,\
- trunc, zext, bitcast, shr_prefix, define, i8, i16, i32
+ trunc, zext, bitcast, shr_prefix, define, i1, i8, i16, i32, f64
+pi8 = i8 + '*'
+pi32 = i32 + '*'
+u32 = i32
+
LINENO = option.lineno
PRINT_SOURCE = option.print_source
PRINT_DEBUG = option.print_debug
-WORD = 4
-
class ParseException(Exception):
pass
@@ -89,56 +92,60 @@
def __init__(self, type):
self.n = count.n_vars
self.type = type
- self.signed = type is i32 or type is 'float'
+ self.signed = type is i32 or type is f64
count.n_vars += 1
def operand(self):
- return '%s %%v%d' % (self.type, self.n)
+ return '%s %s' % (self.type, self.operand2())
def operand2(self):
return '%%v%d' % (self.n,)
class GenericConst(GenConst):
- #type = 'generic'
-
- #def __init__(self, value):
- # self.value = value
def operand(self):
- return '%s %s' % (self.type, self.value)
-
- def operand2(self):
- return str(self.value)
+ return '%s %s' % (self.type, self.operand2())
@specialize.arg(1)
def revealconst(self, T):
if isinstance(T, lltype.Ptr):
- return lltype.cast_int_to_ptr(T, self.value)
+ return lltype.cast_int_to_ptr(T, self.get_integer_value())
elif T is llmemory.Address:
- return llmemory.cast_int_to_adr(self.value)
+ return llmemory.cast_int_to_adr(self.get_integer_value())
else:
- return lltype.cast_primitive(T, self.value)
+ return lltype.cast_primitive(T, self.get_integer_value())
class BoolConst(GenericConst):
- type = 'bool'
+ type = i1
signed = False
def __init__(self, value):
self.value = bool(value)
+ def operand2(self):
+ if self.value:
+ return 'true'
+ else:
+ return 'false'
+
+ def get_integer_value(self):
+ return int(self.value)
+
class CharConst(GenericConst):
type = i8
signed = False
def __init__(self, value):
- if type(value) is str:
- self.value = ord(value)
- else:
- assert type(value) is int
- self.value = value
+ self.value = ord(value)
+
+ def operand2(self):
+ return '%d' % self.value
+
+ def get_integer_value(self):
+ return self.value
class UniCharConst(GenericConst):
@@ -148,6 +155,12 @@
def __init__(self, value):
self.value = unicode(value)
+ def operand2(self):
+ return '%s' % self.value
+
+ def get_integer_value(self):
+ return int(self.value)
+
class IntConst(GenericConst):
type = i32
@@ -156,42 +169,58 @@
def __init__(self, value):
self.value = int(value)
- #XXX why does typeof value change in test_genc_ts.py -k test_degenerated_before_return(_2)?
- def operand(self):
- return '%s %d' % (self.type, int(self.value))
-
def operand2(self):
- return str(int(self.value))
+ return str(self.value)
+
+ def get_integer_value(self):
+ return self.value
class UIntConst(GenericConst):
- type = i32 #'uint'
+ type = u32
signed = False
def __init__(self, value):
- self.value = int(value)
+ self.value = value
+
+ def operand2(self):
+ return str(self.value)
+
+ def get_integer_value(self):
+ return intmask(self.value)
class FloatConst(GenericConst):
- type = 'float'
+ type = f64
signed = True
def __init__(self, value):
self.value = float(value)
+ def operand2(self):
+ return str(self.value)
+
+ @specialize.arg(1)
+ def revealconst(self, T):
+ assert T is lltype.Float
+ return self.value
+
class AddrConst(GenConst):
- type = i32 + '*'
+ type = pi8
signed = False
def __init__(self, addr):
self.addr = addr
def operand(self):
- return '%s %s' % (self.type, llmemory.cast_adr_to_int(self.addr))
+ return '%s %s' % (self.type, self.operand2())
def operand2(self):
- return str(llmemory.cast_adr_to_int(self.addr))
+ s = str(llmemory.cast_adr_to_int(self.addr))
+ if s == '0':
+ s = 'null'
+ return s
@specialize.arg(1)
def revealconst(self, T):
@@ -433,52 +462,52 @@
def op_float_neg(self, gv_x): return self._rgenop2_generic('sub', FloatConst(0.0), gv_x)
def op_int_lt(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'lt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'lt', gv_x, gv_y, i1)
def op_int_le(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'le', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'le', gv_x, gv_y, i1)
def op_int_eq(self, gv_x, gv_y):
- return self._rgenop2_generic(icmp + 'eq' , gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(icmp + 'eq' , gv_x, gv_y, i1)
def op_int_ne(self, gv_x, gv_y):
- return self._rgenop2_generic(icmp + 'ne' , gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(icmp + 'ne' , gv_x, gv_y, i1)
def op_int_gt(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'gt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'gt', gv_x, gv_y, i1)
def op_int_ge(self, gv_x, gv_y):
- return self._rgenop2_generic(scmp + 'ge', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(scmp + 'ge', gv_x, gv_y, i1)
def op_uint_lt(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'lt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'lt', gv_x, gv_y, i1)
def op_uint_le(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'le', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'le', gv_x, gv_y, i1)
def op_uint_gt(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'gt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'gt', gv_x, gv_y, i1)
def op_uint_ge(self, gv_x, gv_y):
- return self._rgenop2_generic(ucmp + 'ge', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(ucmp + 'ge', gv_x, gv_y, i1)
def op_float_lt(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'lt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'lt', gv_x, gv_y, i1)
def op_float_le(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'le', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'le', gv_x, gv_y, i1)
def op_float_eq(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'eq', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'eq', gv_x, gv_y, i1)
def op_float_ne(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'ne', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'ne', gv_x, gv_y, i1)
def op_float_gt(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'gt', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'gt', gv_x, gv_y, i1)
def op_float_ge(self, gv_x, gv_y):
- return self._rgenop2_generic(fcmp + 'ge', gv_x, gv_y, 'bool')
+ return self._rgenop2_generic(fcmp + 'ge', gv_x, gv_y, i1)
op_unichar_eq = op_ptr_eq = op_uint_eq = op_int_eq
op_unichar_ne = op_ptr_ne = op_uint_ne = op_int_ne
@@ -504,14 +533,15 @@
def op_uint_invert(self, gv_x): return self._rgenop2_generic('xor', gv_x, UIntConst((1<<32)-1))
def _abs(self, gv_x, nullstr='0'):
- gv_comp = Var('bool')
+ gv_comp = Var(i1)
gv_abs_pos = Var(gv_x.type)
gv_result = Var(gv_x.type)
- if nullstr is '0':
- l = ' %s=' + scmp + 'ge %s,%s'
+ if nullstr == 'null' or nullstr == '0':
+ cmp = scmp
else:
- l = ' %s=' + fcmp + 'ge %s,%s'
- self.asm.append(l % (gv_comp.operand2(), gv_x.operand(), nullstr))
+ cmp = fcmp
+ self.asm.append(' %s=%sge %s,%s' % (
+ gv_comp.operand2(), cmp, gv_x.operand(), nullstr))
self.asm.append(' %s=sub %s %s,%s' % (
gv_abs_pos.operand2(), gv_x.type, nullstr, gv_x.operand2()))
self.asm.append(' %s=select %s,%s,%s' % (
@@ -539,8 +569,12 @@
if restype is gv_x.type:
return self.genop_same_as(None, gv_x)
gv_result = Var(restype)
+ if restype[-1] == '*':
+ t = bitcast
+ else:
+ t = zext
self.asm.append(' %s=%s %s to %s' % (
- gv_result.operand2(), zext, gv_x.operand(), restype))
+ gv_result.operand2(), t, gv_x.operand(), restype))
return gv_result
def _trunc_to(self, gv_x, restype=None):
@@ -552,19 +586,19 @@
gv_result.operand2(), trunc, gv_x.operand(), restype))
return gv_result
- def _cast_to_bool(self, gv_x): return self._cast_to(gv_x, 'bool')
+ def _cast_to_bool(self, gv_x): return self._cast_to(gv_x, i1)
def _cast_to_char(self, gv_x): return self._cast_to(gv_x, i8)
def _cast_to_unichar(self, gv_x): return self._cast_to(gv_x, i32)
def _cast_to_int(self, gv_x): return self._cast_to(gv_x, i32)
- def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, i32) #'uint')
- def _cast_to_float(self, gv_x): return self._cast_to(gv_x, 'float')
+ def _cast_to_uint(self, gv_x): return self._cast_to(gv_x, u32)
+ def _cast_to_float(self, gv_x): return self._cast_to(gv_x, f64)
- def _trunc_to_bool(self, gv_x): return self._trunc_to(gv_x, 'bool')
+ def _trunc_to_bool(self, gv_x): return self._trunc_to(gv_x, i1)
def _trunc_to_char(self, gv_x): return self._trunc_to(gv_x, i8)
def _trunc_to_unichar(self, gv_x): return self._trunc_to(gv_x, i32)
def _trunc_to_int(self, gv_x): return self._trunc_to(gv_x, i32)
- def _trunc_to_uint(self, gv_x): return self._trunc_to(gv_x, i32) #'uint')
- def _trunc_to_float(self, gv_x): return self._trunc_to(gv_x, 'float')
+ def _trunc_to_uint(self, gv_x): return self._trunc_to(gv_x, u32)
+ def _trunc_to_float(self, gv_x): return self._trunc_to(gv_x, f64)
op_cast_char_to_bool = _trunc_to_bool
op_cast_unichar_to_bool = _trunc_to_bool
@@ -645,104 +679,70 @@
def _is_false(self, gv_x, nullstr='0'):
log('%s Builder._is_false %s' % (self.block.label, gv_x.operand()))
- gv_result = Var('bool')
- if nullstr is '0':
- l = ' %s=' + icmp + 'eq %s,%s'
+ gv_result = Var(i1)
+ if nullstr == 'null' or nullstr == '0':
+ cmp = icmp
else:
- l = ' %s=' + fcmp + 'eq %s,%s'
- self.asm.append(l % (gv_result.operand2(), gv_x.operand(), nullstr))
+ cmp = fcmp
+ self.asm.append(' %s=%seq %s,%s' % (
+ gv_result.operand2(), cmp, gv_x.operand(), nullstr))
return gv_result
def _is_true(self, gv_x, nullstr='0'):
log('%s Builder._is_true %s' % (self.block.label, gv_x.operand()))
- gv_result = Var('bool')
- if nullstr is '0':
- l = ' %s=' + icmp + 'ne %s,%s'
+ gv_result = Var(i1)
+ if nullstr == 'null' or nullstr == '0':
+ cmp = icmp
else:
- l = ' %s=' + fcmp + 'ne %s,%s'
- self.asm.append(l % (gv_result.operand2(), gv_x.operand(), nullstr))
+ cmp = fcmp
+ self.asm.append(' %s=%sne %s,%s' % (
+ gv_result.operand2(), cmp, gv_x.operand(), nullstr))
return gv_result
op_bool_is_true = op_char_is_true = op_unichar_is_true = op_int_is_true =\
- op_uint_is_true = op_ptr_nonzero = _is_true
-
- op_ptr_iszero = _is_false
+ op_uint_is_true = _is_true
+
+ def op_ptr_nonzero(self, gv_x): return self._is_true(gv_x, 'null')
+ def op_ptr_iszero(self, gv_x): return self._is_false(gv_x, 'null')
- def op_float_is_true(self, gv_x): return self._is_true(gv_x, '0.0')
+ def op_float_is_true(self, gv_x): return self._is_true(gv_x, '0.0') #XXX fails for doubles
- def genop_getfield(self, (offset, fieldsize), gv_ptr):
- log('%s Builder.genop_getfield (%d,%d) %s' % (
- self.block.label, offset, fieldsize, gv_ptr.operand()))
- if fieldsize == WORD:
- t = i32
- else:
- if fieldsize == 1:
- t = i8
- else:
- if fieldsize != 2:
- logger.dump('assert fails on: fieldsize != [124]')
- self.rgenop._dump_partial_lines()
- assert fieldsize == 2
- t = i16
+ def genop_getfield(self, fieldtoken, gv_ptr):
+ offset, fieldtype = fieldtoken
+ log('%s Builder.genop_getfield (%d,%s) %s' % (
+ self.block.label, offset, fieldtype, gv_ptr.operand()))
gv_ptr_var = self._as_var(gv_ptr)
- gv_p = Var(t + '*')
+ gv_p = Var(gv_ptr.type)
self.asm.append(' %s=getelementptr %s,%s %s' % (
- gv_p.operand2(), gv_ptr_var.operand(), i32, offset / fieldsize))
- gv_result = Var(t)
+ gv_p.operand2(), gv_ptr_var.operand(), i32, offset))
+ gv_p2 = self._cast_to(gv_p, fieldtype + '*')
+ gv_result = Var(fieldtype)
self.asm.append(' %s=load %s' % (
- gv_result.operand2(), gv_p.operand()))
+ gv_result.operand2(), gv_p2.operand()))
return gv_result
- def genop_setfield(self, (offset, fieldsize), gv_ptr, gv_value):
- log('%s Builder.genop_setfield (%d,%d) %s=%s' % (
- self.block.label, offset, fieldsize, gv_ptr.operand(), gv_value.operand()))
- #if fieldsize == WORD:
- # gv_result = Var(i32)
- #else:
- # if fieldsize == 1:
- # gv_result = Var(i8)
- # else:
- # assert fieldsize == 2
- # gv_result = Var(i16)
+ def genop_setfield(self, fieldtoken, gv_ptr, gv_value):
+ offset, fieldtype = fieldtoken
+ log('%s Builder.genop_setfield (%d,%s) %s=%s' % (
+ self.block.label, offset, fieldtype, gv_ptr.operand(), gv_value.operand()))
gv_ptr_var = self._as_var(gv_ptr)
- gv_p = Var(gv_value.type+'*')
+ gv_p = Var(gv_ptr.type)
self.asm.append(' %s=getelementptr %s,%s %s' % (
- gv_p.operand2(), gv_ptr_var.operand(), i32, offset / fieldsize))
+ gv_p.operand2(), gv_ptr_var.operand(), i32, offset))
+ gv_p2 = self._cast_to(gv_p, fieldtype + '*')
self.asm.append(' store %s,%s' % (
- gv_value.operand(), gv_p.operand()))
+ gv_value.operand(), gv_p2.operand()))
- def genop_getsubstruct(self, (offset, fieldsize), gv_ptr):
- log('%s Builder.genop_getsubstruct (%d,%d) %s' % (
- self.block.label, offset, fieldsize, gv_ptr.operand()))
+ def genop_getsubstruct(self, fieldtoken, gv_ptr):
+ offset, fieldtype = fieldtoken
+ log('%s Builder.genop_getsubstruct (%d,%s) %s' % (
+ self.block.label, offset, fieldtype, gv_ptr.operand()))
gv_ptr_var = self._as_var(gv_ptr)
gv_sub = Var(gv_ptr.type)
- self.asm.append(' %s=getelementptr %s,%d' % (
- gv_sub.operand2(), gv_ptr_var.operand(), offset))
+ self.asm.append(' %s=getelementptr %s,%s %d' % (
+ gv_sub.operand2(), gv_ptr_var.operand(), i32, offset))
return gv_sub
- def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
- array_length_offset, array_items_offset, itemsize = arraytoken
- log('%s Builder.genop_getarrayitem %s,%s,%s' % (
- self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
-
- gv_i = Var(gv_index.type)
- try:
- offset = array_items_offset / itemsize
- except TypeError:
- offset = 4 #XXX (get inspired by ppc backend)
- self.asm.append(' %s=add %s,%d' % (
- gv_i.operand2(), gv_index.operand(), offset)) #/itemsize correct?
-
- gv_ptr_var = self._as_var(gv_ptr)
- gv_p = Var(gv_ptr_var.type)
- self.asm.append(' %s=getelementptr %s,%s' % (
- gv_p.operand2(), gv_ptr_var.operand(), gv_i.operand()))
-
- gv_result = Var(gv_ptr_var.type[:-1])
- self.asm.append(' %s=load %s' % (
- gv_result.operand2(), gv_p.operand()))
- return gv_result
-
def genop_getarraysubstruct(self, arraytoken, gv_ptr, gv_index):
'''
self.mc.MOV(edx, gv_ptr.operand(self))
@@ -750,28 +750,39 @@
self.mc.LEA(eax, op)
return self.returnvar(eax)
'''
- #XXX TODO
- array_length_offset, array_items_offset, itemsize = arraytoken
- gv_result = Var(i32)
+ #XXX WIP
log('%s Builder.genop_getarraysubstruct %s,%s,%s' % (
- self.block.label, arraytoken, gv_ptr, gv_index))
- self.asm.append(' %s=%s 0 ;%s Builder.genop_getarraysubstruct %s,%s,%s' % (
- gv_result.operand2(), gv_result.type, self.block.label, arraytoken, gv_ptr, gv_index))
+ self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
+
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
+
+ op_size = self._itemaddr(arraytoken, gv_index)
+
+ gv_ptr_var = self._as_var(gv_ptr)
+
+ gv_result = Var(pi8)
+ self.asm.append(' %s=getelementptr %s,%s' % (
+ gv_result.operand2(), gv_ptr_var.operand(), op_size.operand()))
+
return gv_result
def genop_getarraysize(self, arraytoken, gv_ptr):
- '''
- lengthoffset, startoffset, itemoffset = arraytoken
- self.mc.MOV(edx, gv_ptr.operand(self))
- return self.returnvar(mem(edx, lengthoffset))
- '''
- #XXX TODO
- array_length_offset, array_items_offset, itemsize = arraytoken
- gv_result = Var(i32)
log('%s Builder.genop_getarraysize %s,%s' % (
- self.block.label, arraytoken, gv_ptr))
- self.asm.append(' %s=%s 0 ;%s Builder.genop_getarraysize %s,%s' % (
- gv_result.operand2(), gv_result.type, self.block.label, arraytoken, gv_ptr))
+ self.block.label, arraytoken, gv_ptr.operand()))
+
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
+ gv_ptr_var = self._as_var(gv_ptr)
+
+ gv_p = Var(gv_ptr_var.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, array_length_offset))
+
+ gv_p2 = self._cast_to(gv_p, pi32)
+
+ gv_result = Var(i32)
+ self.asm.append(' %s=load %s' % (
+ gv_result.operand2(), gv_p2.operand()))
+
return gv_result
def _as_var(self, gv):
@@ -782,34 +793,56 @@
gv_var.operand2(), inttoptr, i32, gv.operand2(), gv_var.type))
return gv_var
return gv
-
+
+ def genop_getarrayitem(self, arraytoken, gv_ptr, gv_index):
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
+ log('%s Builder.genop_getarrayitem %s,%s[%s]' % (
+ self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand()))
+
+ gv_ptr_var = self._as_var(gv_ptr)
+
+ gv_p = Var(gv_ptr_var.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, array_items_offset))
+
+ gv_p2 = self._cast_to(gv_p, item_type + '*')
+
+ gv_p3 = Var(gv_p2.type)
+ self.asm.append(' %s=getelementptr %s,%s' % (
+ gv_p3.operand2(), gv_p2.operand(), gv_index.operand()))
+
+ gv_result = Var(item_type)
+ self.asm.append(' %s=load %s' % (
+ gv_result.operand2(), gv_p3.operand()))
+
+ return gv_result
+
def genop_setarrayitem(self, arraytoken, gv_ptr, gv_index, gv_value):
- array_length_offset, array_items_offset, itemsize = arraytoken
- log('%s Builder.genop_setarrayitem %s,%s,%s,%s' % (
+ array_length_offset, array_items_offset, item_size, item_type = arraytoken
+ log('%s Builder.genop_setarrayitem %s,%s[%s]=%s' % (
self.block.label, arraytoken, gv_ptr.operand(), gv_index.operand(), gv_value.operand()))
- try:
- offset = array_items_offset / itemsize
- except TypeError:
- offset = 4 #XXX (get inspired by ppc backend)
- gv_i = Var(gv_index.type)
- self.asm.append(' %s=add %s,%d ;;;;' % (
- gv_i.operand2(), gv_index.operand(), offset)) #/itemsize correct?
-
gv_ptr_var = self._as_var(gv_ptr)
+
gv_p = Var(gv_ptr_var.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_ptr_var.operand(), i32, array_items_offset))
+
+ gv_p2 = self._cast_to(gv_p, item_type + '*')
+
+ gv_p3 = Var(gv_p2.type)
self.asm.append(' %s=getelementptr %s,%s' % (
- gv_p.operand2(), gv_ptr_var.operand(), gv_i.operand()))
+ gv_p3.operand2(), gv_p2.operand(), gv_index.operand()))
+
self.asm.append(' store %s,%s' % (
- gv_value.operand(), gv_p.operand()))
+ gv_value.operand(), gv_p3.operand()))
def genop_malloc_fixedsize(self, size):
log('%s Builder.genop_malloc_fixedsize %s' % (
self.block.label, str(size)))
- t = i8 + '*' #XXX or opaque* ?
- gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
- gv_result = Var(t)
- #XXX or use addGlobalFunctionMapping in libllvmjit.restart()
+ gv_gc_malloc_fnaddr = Var('%s (%s)*' % (pi8, i32))
+ gv_result = Var(pi8)
+ #or use addGlobalFunctionMapping in libllvmjit.restart()
self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr' % (
gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
@@ -817,19 +850,44 @@
gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), i32, size))
return gv_result
+ def _itemaddr(self, arraytoken, gv_index):
+ length_offset, items_offset, item_size, item_type = arraytoken
+
+ gv_size2 = Var(i32) #i386 uses self.itemaddr here
+ self.asm.append(' %s=mul %s,%d' % (
+ gv_size2.operand2(), gv_index.operand(), item_size))
+
+ gv_size3 = Var(i32)
+ self.asm.append(' %s=add %s,%d' % (
+ gv_size3.operand2(), gv_size2.operand(), items_offset))
+
+ return gv_size3
+
def genop_malloc_varsize(self, varsizealloctoken, gv_size):
log('%s Builder.genop_malloc_varsize %s,%s' % (
self.block.label, varsizealloctoken, gv_size.operand()))
- t = i8 + '*' #XXX or opaque* ?
- gv_gc_malloc_fnaddr = Var('%s (%s)*' % (t, i32))
- gv_result = Var(t)
- #XXX or use addGlobalFunctionMapping in libllvmjit.restart()
+
+ length_offset, items_offset, item_size, item_type = varsizealloctoken
+
+ gv_gc_malloc_fnaddr = Var('%s (%s)*' % (pi8, i32))
+ #or use addGlobalFunctionMapping in libllvmjit.restart()
self.asm.append(' %s=%s %s %d to %s ;gc_malloc_fnaddr (varsize)' % (
gv_gc_malloc_fnaddr.operand2(), inttoptr, i32,
gc_malloc_fnaddr(), gv_gc_malloc_fnaddr.type))
+
+ op_size = self._itemaddr(varsizealloctoken, gv_size)
+
+ gv_result = Var(pi8)
self.asm.append(' %s=call %s(%s)' % (
- gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), gv_size.operand()))
- #XXX TODO set length field
+ gv_result.operand2(), gv_gc_malloc_fnaddr.operand(), op_size.operand()))
+
+ gv_p = Var(gv_result.type)
+ self.asm.append(' %s=getelementptr %s,%s %s' % (
+ gv_p.operand2(), gv_result.operand(), i32, length_offset))
+
+ gv_p2 = self._cast_to(gv_p, pi32) #warning: length field hardcoded as int here
+ self.asm.append(' store %s, %s' % (gv_size.operand(), gv_p2.operand()))
+
return gv_result
def _funcsig_type(self, args_gv, restype):
@@ -839,15 +897,15 @@
log('%s Builder.genop_call %s,%s,%s' % (
self.block.label, sigtoken, gv_fnptr, [v.operand() for v in args_gv]))
argtypes, restype = sigtoken
- gv_returnvar = Var(restype)
if isinstance(gv_fnptr, AddrConst):
- gv_fn = Var(self._funcsig_type(args_gv, restype))
- self.asm.append(' %s=%s %s to %s' % (
- gv_fnptr.operand2(), bitcast, gv_fnptr.operand(), gv_fn.type))
+ gv_fn = Var(self._funcsig_type(args_gv, restype) + '*')
+ self.asm.append(' %s=%s %s %s to %s' % (
+ gv_fn.operand2(), bitcast, i32, gv_fnptr.operand2(), gv_fn.type))
funcsig = gv_fn.operand()
else:
#XXX we probably need to call an address directly if we can't resolve the funcsig
funcsig = self.rgenop.funcsig[gv_fnptr.value]
+ gv_returnvar = Var(restype)
self.asm.append(' %s=call %s(%s)' % (
gv_returnvar.operand2(),
funcsig,
@@ -862,6 +920,7 @@
def finish_and_goto(self, outputargs_gv, target):
# 'target' is a label, which for the llvm backend is a Block
+ log('%s Builder.finish_and_goto' % self.block.label)
gv = [v.operand() for v in outputargs_gv]
log('%s Builder.finish_and_goto %s,%s' % (
self.block.label, gv, target.label))
@@ -974,18 +1033,16 @@
def kindToken(T):
# turn the type T into the llvm approximation that we'll use here
# XXX incomplete
- if isinstance(T, lltype.Ptr):
- return i32 + '*' #or opaque* ?
- elif T is llmemory.Address:
- return i32 + '*' #or apaque* ?
- if T is lltype.Bool:
- return 'bool'
+ if isinstance(T, lltype.Ptr) or T is llmemory.Address:
+ return pi8
+ elif T is lltype.Bool:
+ return i1
elif T is lltype.Char:
return i8
elif T is lltype.Unsigned:
- return i32 #'uint'
+ return u32
elif T is lltype.Float:
- return 'float'
+ return f64
else:
return i32 #Signed/UniChar/Void
@@ -994,10 +1051,10 @@
def fieldToken(T, name):
FIELD = getattr(T, name)
if isinstance(FIELD, lltype.ContainerType):
- fieldsize = 0 # not useful for getsubstruct
+ fieldtype = pi8 # not useful for getsubstruct
else:
- fieldsize = llmemory.sizeof(FIELD)
- return (llmemory.offsetof(T, name), fieldsize)
+ fieldtype = RLLVMGenOp.kindToken(FIELD)
+ return (llmemory.offsetof(T, name), fieldtype)
@staticmethod
@specialize.memo()
@@ -1015,19 +1072,20 @@
arrayfield = T._arrayfld
ARRAYFIELD = getattr(T, arrayfield)
arraytoken = RLLVMGenOp.arrayToken(ARRAYFIELD)
- length_offset, items_offset, item_size = arraytoken
+ length_offset, items_offset, item_size, item_type = arraytoken
arrayfield_offset = llmemory.offsetof(T, arrayfield)
return (arrayfield_offset+length_offset,
arrayfield_offset+items_offset,
- item_size)
+ item_size,
+ item_type)
@staticmethod
@specialize.memo()
def arrayToken(A):
- #XXX TODO
return (llmemory.ArrayLengthOffset(A),
llmemory.ArrayItemsOffset(A),
- llmemory.ItemOffset(A.OF))
+ llmemory.ItemOffset(A.OF),
+ RLLVMGenOp.kindToken(A.OF))
@staticmethod
@specialize.memo()
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_exception.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_exception.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_exception.py Sat Jan 13 12:09:25 2007
@@ -2,7 +2,6 @@
from pypy.jit.timeshifter.test import test_exception
from pypy.jit.codegen.llvm.test.test_genc_ts import LLVMTimeshiftingTestMixin
-py.test.skip("WIP")
class TestException(LLVMTimeshiftingTestMixin,
test_exception.TestException):
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py Sat Jan 13 12:09:25 2007
@@ -5,10 +5,6 @@
from pypy.jit.codegen.llvm.llvmjit import llvm_version, MINIMAL_VERSION
-skip_passing = False
-skip_failing = True
-
-
class LLVMTimeshiftingTestMixin(I386TimeshiftingTestMixin):
RGenOp = RLLVMGenOp
@@ -29,61 +25,7 @@
if llvm_version() < 2.0:
test_loop_merging = skip_too_minimal #segfault
test_two_loops_merging = skip_too_minimal #segfault
-
- if skip_passing:
- test_very_simple = skip
- test_convert_const_to_redbox = skip
- test_simple_opt_const_propagation2 = skip
- test_simple_opt_const_propagation1 = skip
- test_loop_folding = skip
- test_loop_merging = skip
- test_two_loops_merging = skip
- test_convert_greenvar_to_redvar = skip
- test_green_across_split = skip
- test_merge_const_before_return = skip
- test_merge_3_redconsts_before_return = skip
- test_arith_plus_minus = skip
- test_plus_minus_all_inlined = skip
- test_call_simple = skip
- test_call_2 = skip
- test_call_3 = skip
- test_call_4 = skip
- test_void_call = skip
- test_green_call = skip
- test_split_on_green_return = skip
- test_recursive_call = skip
- test_simple_indirect_call = skip
- test_normalize_indirect_call = skip
- test_normalize_indirect_call_more = skip
- test_green_red_mismatch_in_call = skip
- test_red_call_ignored_result = skip
- test_simple_struct = skip
- test_simple_array = skip
- test_setarrayitem = skip
- test_degenerated_before_return = skip
- test_degenerated_before_return_2 = skip
- test_degenerated_via_substructure = skip
- test_red_virtual_container = skip
- test_red_propagate = skip
- test_red_subcontainer = skip
- test_red_subcontainer_cast = skip
- test_merge_structures = skip
- test_simple_meth = skip
- test_simple_red_meth = skip
-
- #failing...
- if skip_failing:
- test_degenerated_at_return = skip
- test_degenerate_with_voids = skip
- test_red_array = skip
- test_red_struct_array = skip
- test_red_varsized_struct = skip
- test_array_of_voids = skip
- test_green_with_side_effects = skip
- test_recursive_with_red_termination_condition = skip
- test_compile_time_const_tuple = skip
- test_residual_red_call = skip
+ test_green_char_at_merge = skip #segfault
test_residual_red_call_with_exc = skip
-
- test_green_char_at_merge = skip #->SomeObject() (CharRepr @rgenop.py:141 ?)
-
+ else: #needs fixing for >= 2.0
+ test_array_of_voids = skip
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_vlist.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_vlist.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_vlist.py Sat Jan 13 12:09:25 2007
@@ -3,12 +3,13 @@
from pypy.jit.codegen.llvm.test.test_genc_ts import LLVMTimeshiftingTestMixin
-py.test.skip('WIP')
-
class TestVList(LLVMTimeshiftingTestMixin,
test_vlist.TestVList):
# for the individual tests see
# ====> ../../../timeshifter/test/test_vlist.py
- pass
+ def skip(self):
+ py.test.skip("WIP")
+
+ test_force = skip
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_operation.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_operation.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_operation.py Sat Jan 13 12:09:25 2007
@@ -1,12 +1,47 @@
import py
+from pypy.rlib.objectmodel import specialize
+from pypy.rpython.memory.lltypelayout import convert_offset_to_int
from pypy.jit.codegen.llvm.test.test_llvmjit import skip_unsupported_platform
from pypy.jit.codegen.i386.test.test_operation import BasicTests
from pypy.jit.codegen.llvm.rgenop import RLLVMGenOp
from pypy.jit.codegen.llvm.llvmjit import llvm_version, MINIMAL_VERSION
+def conv(n):
+ if not isinstance(n, int) and not isinstance(n, str):
+ n = convert_offset_to_int(n)
+ return n
+
+
+class RGenOpPacked(RLLVMGenOp):
+ """Like RLLVMGenOp, but produces concrete offsets in the tokens
+ instead of llmemory.offsets. These numbers may not agree with
+ your C compiler's.
+ """
+
+ @staticmethod
+ @specialize.memo()
+ def fieldToken(T, name):
+ return tuple(map(conv, RLLVMGenOp.fieldToken(T, name)))
+
+ @staticmethod
+ @specialize.memo()
+ def arrayToken(A):
+ return tuple(map(conv, RLLVMGenOp.arrayToken(A)))
+
+ @staticmethod
+ @specialize.memo()
+ def allocToken(T):
+ return conv(RLLVMGenOp.allocToken(T))
+
+ @staticmethod
+ @specialize.memo()
+ def varsizeAllocToken(A):
+ return tuple(map(conv, RLLVMGenOp.varsizeAllocToken(A)))
+
+
class LLVMTestBasicMixin(object):
- RGenOp = RLLVMGenOp
+ RGenOp = RGenOpPacked
class TestBasic(LLVMTestBasicMixin,
@@ -23,9 +58,11 @@
llvm_version(), MINIMAL_VERSION))
if llvm_version() < 2.0:
- test_float_arithmetic = skip_too_minimal #segfault
test_unsigned = skip_too_minimal #uint_invert uses incorrect xor constant?
+ test_float_arithmetic = skip #XXX llvmjit.execute() returns an int :-(
+ test_float_cast = skip #XXX llvmjit.execute() returns an int :-(
+
test_float_pow = skip
test_unichar_array = skip
test_char_unichar_fields = skip
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py Sat Jan 13 12:09:25 2007
@@ -25,3 +25,5 @@
test_fact_direct = skip_too_minimal #segfault
test_fact_compile = skip #XXX Blocked block, introducted by this checkin (I don't understand)
+ test_calling_pause_direct = skip #segfault, look into later...
+ test_calling_pause_compile = skip # dito
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/model.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/model.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/model.py Sat Jan 13 12:09:25 2007
@@ -171,6 +171,15 @@
def start_writing(self):
'''Start a builder returned by jump_if_xxx(), or resumes a paused
builder.'''
+
+
+ # read frame var support
+
+ def get_frame_base(self):
+ pass
+
+ def get_frame_info(self):
+ pass
class GenLabel(object):
'''A "smart" label. Represents an address of the start of a basic
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/instruction.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/instruction.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/instruction.py Sat Jan 13 12:09:25 2007
@@ -6,11 +6,24 @@
rFP = r2 # the ABI doesn't specify a frame pointer. however, we want one
class AllocationSlot(object):
- pass
+ def __init__(self):
+ # The field alloc points to a singleton used by the register
+ # allocator to detect conflicts. No two AllocationSlot
+ # instances with the same value in self.alloc can be used at
+ # once.
+ self.alloc = self
+
+ def make_loc(self):
+ """ When we assign a variable to one of these registers, we
+ call make_loc() to get the actual location instance; that
+ instance will have its alloc field set to self. For
+ everything but condition registers, this is self."""
+ return self
class _StackSlot(AllocationSlot):
is_register = False
def __init__(self, offset):
+ AllocationSlot.__init__(self)
self.offset = offset
def __repr__(self):
return "stack@%s"%(self.offset,)
@@ -34,10 +47,13 @@
class Register(AllocationSlot):
is_register = True
+ def __init__(self):
+ AllocationSlot.__init__(self)
class GPR(Register):
regclass = GP_REGISTER
def __init__(self, number):
+ Register.__init__(self)
self.number = number
def __repr__(self):
return 'r' + str(self.number)
@@ -46,19 +62,46 @@
class FPR(Register):
regclass = FP_REGISTER
def __init__(self, number):
+ Register.__init__(self)
self.number = number
fprs = map(GPR, range(32))
-class CRF(Register):
+class BaseCRF(Register):
+ """ These represent condition registers; however, we never actually
+ use these as the location of something in the register allocator.
+ Instead, we place it in an instance of CRF which indicates which
+ bits are required to extract the value. Note that CRF().alloc will
+ always be an instance of this. """
regclass = CR_FIELD
def __init__(self, number):
self.number = number
- def move_to_gpr(self, allocator, gpr):
- bit, negated = allocator.crfinfo[self.number]
- return _CRF2GPR(gpr, self.number*4 + bit, negated)
+ self.alloc = self
+ def make_loc(self):
+ return CRF(self)
+
+crfs = map(BaseCRF, range(8))
-crfs = map(CRF, range(8))
+class CRF(Register):
+ regclass = CR_FIELD
+ def __init__(self, crf):
+ Register.__init__(self)
+ self.alloc = crf
+ self.number = crf.number
+ self.info = (-1,-1) # (bit, negated)
+ def set_info(self, info):
+ assert len(info) == 2
+ self.info = info
+ def make_loc(self):
+ # should never call this on a CRF, only a BaseCRF
+ raise NotImplementedError
+ def move_to_gpr(self, allocator, gpr):
+ bit, negated = self.info
+ return _CRF2GPR(gpr, self.alloc.number*4 + bit, negated)
+ def move_from_gpr(self, allocator, gpr):
+ # cmp2info['ne']
+ self.set_info((2, 1))
+ return _GPR2CRF(self, gpr)
class CTR(Register):
regclass = CT_REGISTER
@@ -169,6 +212,24 @@
self.result_reg.number,
self.imm.value)
+class MoveCRB2GPR(Insn):
+ def __init__(self, result, gv_condition):
+ Insn.__init__(self)
+ self.result = result
+ self.result_regclass = GP_REGISTER
+ self.reg_args = [gv_condition]
+ self.reg_arg_regclasses = [CR_FIELD]
+ def allocate(self, allocator):
+ self.targetreg = allocator.loc_of(self.result)
+ self.crf = allocator.loc_of(self.reg_args[0])
+ def emit(self, asm):
+ assert isinstance(self.crf, CRF)
+ bit, negated = self.crf.info
+ asm.mfcr(self.targetreg.number)
+ asm.extrwi(self.targetreg.number, self.targetreg.number, 1, self.crf.number*4+bit)
+ if negated:
+ asm.xori(self.targetreg.number, self.targetreg.number, 1)
+
class Insn_None__GPR_GPR_IMM(Insn):
def __init__(self, methptr, args):
Insn.__init__(self)
@@ -214,47 +275,56 @@
self.reg3.number)
class CMPInsn(Insn):
- info = (0,0) # please the annotator for tests that don't use CMPW/CMPWI
- pass
-
-class CMPW(CMPInsn):
- def __init__(self, info, result, args):
+ def __init__(self, info, result):
Insn.__init__(self)
self.info = info
-
self.result = result
- self.result_regclass = CR_FIELD
+ def allocate(self, allocator):
+ self.result_reg = allocator.loc_of(self.result)
+ assert isinstance(self.result_reg, CRF)
+ self.result_reg.set_info(self.info)
+
+class CMPW(CMPInsn):
+ def __init__(self, info, result, args):
+ CMPInsn.__init__(self, info, result)
+ self.result_regclass = CR_FIELD
self.reg_args = args
self.reg_arg_regclasses = [GP_REGISTER, GP_REGISTER]
def allocate(self, allocator):
- self.result_reg = allocator.loc_of(self.result)
+ CMPInsn.allocate(self, allocator)
self.arg_reg1 = allocator.loc_of(self.reg_args[0])
self.arg_reg2 = allocator.loc_of(self.reg_args[1])
def emit(self, asm):
asm.cmpw(self.result_reg.number, self.arg_reg1.number, self.arg_reg2.number)
+class CMPWL(CMPW):
+ def emit(self, asm):
+ asm.cmpwl(self.result_reg.number, self.arg_reg1.number, self.arg_reg2.number)
+
class CMPWI(CMPInsn):
def __init__(self, info, result, args):
- Insn.__init__(self)
- self.info = info
+ CMPInsn.__init__(self, info, result)
self.imm = args[1]
-
- self.result = result
self.result_regclass = CR_FIELD
-
self.reg_args = [args[0]]
self.reg_arg_regclasses = [GP_REGISTER]
def allocate(self, allocator):
- self.result_reg = allocator.loc_of(self.result)
+ CMPInsn.allocate(self, allocator)
self.arg_reg = allocator.loc_of(self.reg_args[0])
def emit(self, asm):
+ #print "CMPWI", asm.mc.tell()
asm.cmpwi(self.result_reg.number, self.arg_reg.number, self.imm.value)
+class CMPWLI(CMPW):
+ def emit(self, asm):
+ asm.cmpwli(self.result_reg.number, self.arg_reg.number, self.imm.value)
+
+
## class MTCTR(Insn):
## def __init__(self, result, args):
## Insn.__init__(self)
@@ -285,12 +355,12 @@
self.targetbuilder = targetbuilder
def allocate(self, allocator):
self.crf = allocator.loc_of(self.reg_args[0])
- self.bit, self.negated = allocator.crfinfo[self.crf.number]
+ assert self.targetbuilder.initial_var2loc is None
self.targetbuilder.initial_var2loc = {}
for gv_arg in self.jump_args_gv:
self.targetbuilder.initial_var2loc[gv_arg] = allocator.var2loc[gv_arg]
- self.targetbuilder.initial_spill_offset = allocator.spill_offset
+ allocator.builders_to_tell_spill_offset_to.append(self.targetbuilder)
def emit(self, asm):
if self.targetbuilder.start:
asm.load_word(rSCRATCH, self.targetbuilder.start)
@@ -298,11 +368,12 @@
self.targetbuilder.patch_start_here = asm.mc.tell()
asm.load_word(rSCRATCH, 0)
asm.mtctr(rSCRATCH)
- if self.negated ^ self.jump_if_true:
+ bit, negated = self.crf.info
+ if negated ^ self.jump_if_true:
BO = 12 # jump if relavent bit is set in the CR
else:
BO = 4 # jump if relavent bit is NOT set in the CR
- asm.bcctr(BO, self.crf.number*4 + self.bit)
+ asm.bcctr(BO, self.crf.number*4 + bit)
class SpillCalleeSaves(Insn):
def __init__(self):
@@ -384,6 +455,20 @@
self.result_regclass = NO_REGISTER
self.result = None
+class Move(AllocTimeInsn):
+ def __init__(self, dest, src):
+ self.dest = dest
+ self.src = src
+ def emit(self, asm):
+ asm.mr(self.dest.number, self.src.number)
+
+class Load(AllocTimeInsn):
+ def __init__(self, dest, const):
+ self.dest = dest
+ self.const = const
+ def emit(self, asm):
+ self.const.load_now(asm, self.dest)
+
class Unspill(AllocTimeInsn):
""" A special instruction inserted by our register "allocator." It
indicates that we need to load a value from the stack into a register
@@ -432,6 +517,14 @@
if self.negated:
asm.xori(self.targetreg, self.targetreg, 1)
+class _GPR2CRF(AllocTimeInsn):
+ def __init__(self, targetreg, fromreg):
+ AllocTimeInsn.__init__(self)
+ self.targetreg = targetreg
+ self.fromreg = fromreg
+ def emit(self, asm):
+ asm.cmpwi(self.targetreg.number, self.fromreg, 0)
+
class _GPR2CTR(AllocTimeInsn):
def __init__(self, fromreg):
AllocTimeInsn.__init__(self)
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/regalloc.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/regalloc.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/regalloc.py Sat Jan 13 12:09:25 2007
@@ -33,13 +33,11 @@
# go through the initial mapping and initialize the data structures
for var, loc in initial_mapping.iteritems():
self.set(var, loc)
- if loc.is_register and loc in self.freeregs[loc.regclass]:
- self.freeregs[loc.regclass].remove(loc)
+ if loc.is_register and loc.alloc in self.freeregs[loc.regclass]:
+ self.freeregs[loc.regclass].remove(loc.alloc)
self.lru.append(var)
- # crfinfo is a bit of a hack used to transmit which bit a compare
- # instruction set to the branch instruction
- self.crfinfo = [(0, 0)] * 8
+ self.builders_to_tell_spill_offset_to = []
def set(self, var, loc):
assert var not in self.var2loc
@@ -77,7 +75,7 @@
freeregs = self.freeregs[regclass]
if freeregs:
- reg = freeregs.pop()
+ reg = freeregs.pop().make_loc()
self.set(newarg, reg)
if DEBUG_PRINT:
print "allocate_reg: Putting %r into fresh register %r" % (newarg, reg)
@@ -103,7 +101,7 @@
print "allocate_reg: Spilled %r to %r." % (argtospill, self.loc_of(argtospill))
# update data structures to put newarg into the register
- self.set(newarg, reg)
+ self.set(newarg, reg.alloc.make_loc())
if DEBUG_PRINT:
print "allocate_reg: Put %r in stolen reg %r." % (newarg, reg)
return reg
@@ -172,7 +170,7 @@
# it's in the wrong kind of register
# (this code is excessively confusing)
self.forget(arg, argloc)
- self.freeregs[argloc.regclass].append(argloc)
+ self.freeregs[argloc.regclass].append(argloc.alloc)
if argloc.regclass != GP_REGISTER:
if argcls == GP_REGISTER:
gpr = self._allocate_reg(GP_REGISTER, arg).number
@@ -197,8 +195,6 @@
if DEBUG_PRINT:
print "Allocating register for result %r..." % (insn.result,)
resultreg = self._allocate_reg(insn.result_regclass, insn.result)
- if isinstance(insn, CMPInsn):
- self.crfinfo[resultreg.number] = insn.info
insn.allocate(self)
self.insns.append(insn)
return self.insns
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/rgenop.py Sat Jan 13 12:09:25 2007
@@ -1,6 +1,7 @@
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.rpython.lltypesystem import lloperation
from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.jit.codegen.ppc.conftest import option
from ctypes import POINTER, cast, c_void_p, c_int
@@ -20,12 +21,15 @@
def emit(self, value):
self.mc.write(value)
+_PPC = RPPCAssembler
+
NSAVEDREGISTERS = 19
DEBUG_TRAP = option.trap
_var_index = [0]
class Var(GenVar):
+ conditional = False
def __init__(self):
self.__magic_index = _var_index[0]
_var_index[0] += 1
@@ -34,11 +38,16 @@
def fits_in_immediate(self):
return False
+class ConditionVar(Var):
+ """ Used for vars that originated as the result of a conditional
+ operation, like a == b """
+ conditional = True
+
class IntConst(GenConst):
def __init__(self, value):
self.value = value
-
+
@specialize.arg(1)
def revealconst(self, T):
if isinstance(T, lltype.Ptr):
@@ -50,7 +59,7 @@
def load(self, insns, var):
insns.append(
- insn.Insn_GPR__IMM(RPPCAssembler.load_word,
+ insn.Insn_GPR__IMM(_PPC.load_word,
var, [self]))
def load_now(self, asm, loc):
@@ -101,28 +110,39 @@
class JumpPatchupGenerator(object):
- def __init__(self, asm, min_offset):
- self.asm = asm
+ def __init__(self, insns, min_offset, allocator):
+ self.insns = insns
self.min_offset = min_offset
+ self.allocator = allocator
def emit_move(self, tarloc, srcloc):
if tarloc == srcloc: return
+ emit = self.insns.append
if tarloc.is_register and srcloc.is_register:
- self.asm.mr(tarloc.number, srcloc.number)
+ assert isinstance(tarloc, insn.GPR)
+ if isinstance(srcloc, insn.GPR):
+ emit(insn.Move(tarloc, srcloc))
+ else:
+ assert isinstance(srcloc, insn.CRF)
+ emit(srcloc.move_to_gpr(self.allocator, tarloc.number))
elif tarloc.is_register and not srcloc.is_register:
- self.asm.lwz(tarloc.number, rFP, srcloc.offset)
+ emit(insn.Unspill(None, tarloc, srcloc))
+ #self.asm.lwz(tarloc.number, rFP, srcloc.offset)
elif not tarloc.is_register and srcloc.is_register:
- self.asm.stw(srcloc.number, rFP, tarloc.offset)
+ emit(insn.Spill(None, srcloc, tarloc))
+ #self.asm.stw(srcloc.number, rFP, tarloc.offset)
elif not tarloc.is_register and not srcloc.is_register:
- self.asm.lwz(rSCRATCH, rFP, srcloc.offset)
- self.asm.stw(rSCRATCH, rFP, tarloc.offset)
+ emit(insn.Unspill(None, insn.gprs[0], srcloc))
+ emit(insn.Spill(None, insn.gprs[0], tarloc))
+ #self.asm.lwz(rSCRATCH, rFP, srcloc.offset)
+ #self.asm.stw(rSCRATCH, rFP, tarloc.offset)
def create_fresh_location(self):
r = self.min_offset
self.min_offset -= 4
return insn.stack_slot(r)
-def prepare_for_jump(asm, min_offset, sourcevars, src2loc, target):
+def prepare_for_jump(insns, min_offset, sourcevars, src2loc, target, allocator):
tar2src = {} # tar var -> src var
tar2loc = {}
@@ -137,9 +157,9 @@
tar2loc[tloc] = tloc
tar2src[tloc] = src
else:
- src.load_now(asm, tloc)
+ insns.append(insn.Load(tloc, src))
- gen = JumpPatchupGenerator(asm, min_offset)
+ gen = JumpPatchupGenerator(insns, min_offset, allocator)
emit_moves(gen, tar2src, tar2loc, src2loc)
return gen.min_offset
@@ -205,13 +225,19 @@
@specialize.arg(1)
def genop1(self, opname, gv_arg):
+ #print opname, 'on', id(self)
genmethod = getattr(self, 'op_' + opname)
- return genmethod(gv_arg)
+ r = genmethod(gv_arg)
+ #print '->', id(r)
+ return r
@specialize.arg(1)
def genop2(self, opname, gv_arg1, gv_arg2):
+ #print opname, 'on', id(self)
genmethod = getattr(self, 'op_' + opname)
- return genmethod(gv_arg1, gv_arg2)
+ r = genmethod(gv_arg1, gv_arg2)
+ #print '->', id(r)
+ return r
def genop_call(self, sigtoken, gv_fnptr, args_gv):
self.insns.append(insn.SpillCalleeSaves())
@@ -225,14 +251,14 @@
def genop_getfield(self, fieldtoken, gv_ptr):
gv_result = Var()
self.insns.append(
- insn.Insn_GPR__GPR_IMM(RPPCAssembler.lwz,
+ insn.Insn_GPR__GPR_IMM(_PPC.lwz,
gv_result, [gv_ptr, IntConst(fieldtoken)]))
return gv_result
def genop_setfield(self, fieldtoken, gv_ptr, gv_value):
gv_result = Var()
self.insns.append(
- insn.Insn_None__GPR_GPR_IMM(RPPCAssembler.stw,
+ insn.Insn_None__GPR_GPR_IMM(_PPC.stw,
[gv_value, gv_ptr, IntConst(fieldtoken)]))
return gv_result
@@ -322,8 +348,34 @@
## def genop_debug_pdb(self): # may take an args_gv later
def enter_next_block(self, kinds, args_gv):
+ #print 'enter_next_block of', id(self)
vars_gv = [v for v in args_gv if isinstance(v, Var)]
- var2loc = self.allocate_and_emit(vars_gv).var2loc
+ #print 'initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
+ #print 'initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
+ allocator = self.allocate_and_emit(vars_gv)
+ var2loc = allocator.var2loc
+
+ #print '!!!!', args_gv, var2loc
+
+ self.insns = []
+
+ reallocate = False
+ for i in range(len(args_gv)):
+ v = args_gv[i]
+ if isinstance(v, Var) and isinstance(var2loc[v], insn.CRF):
+ reallocate = True
+ nv = Var()
+ self.insns.append(insn.MoveCRB2GPR(nv, v))
+ args_gv[i] = nv
+ self.initial_var2loc = var2loc
+ if reallocate:
+ allocator = self.allocate_and_emit([v for v in args_gv if isinstance(v, Var)])
+ var2loc = allocator.var2loc
+ self.insns = []
+
+ #print 'var2loc.keys():', [id(v) for v in var2loc.keys()]
+ #print 'var2loc.values():', [id(v) for v in var2loc.values()]
+ #print 'args_gv', [id(v) for v in args_gv]
#print "enter_next_block:", args_gv, var2loc
@@ -333,6 +385,11 @@
for gv in args_gv:
if isinstance(gv, Var):
assert gv in var2loc
+## if gv not in var2loc:
+## lloperation.llop.debug_print(lltype.Void, gv)
+## lloperation.llop.debug_print(lltype.Void, var2loc)
+## lloperation.llop.debug_print(lltype.Void, args_gv)
+## lloperation.llop.debug_pdb(lltype.Void)
loc = var2loc[gv]
livevar2loc[gv] = loc
if not loc.is_register:
@@ -360,15 +417,19 @@
#print livevar2loc
- self.insns = []
self.initial_var2loc = livevar2loc
+ #print 'final initial_var2loc.keys():', [id(v) for v in self.initial_var2loc.keys()]
+ #print 'final initial_var2loc.values():', [id(v) for v in self.initial_var2loc.values()]
self.initial_spill_offset = min_stack_offset
target_addr = self.asm.mc.tell()
- self.emit_stack_adjustment()
return Label(target_addr, arg_locations, min_stack_offset)
def jump_if_false(self, gv_condition, args_gv):
- return self._jump(gv_condition, False, args_gv)
+ #print 'jump_if_false', [id(v) for v in args_gv]
+ #print id(self)
+ t = self._jump(gv_condition, False, args_gv)
+ #print '->', id(t)
+ return t
def jump_if_true(self, gv_condition, args_gv):
return self._jump(gv_condition, True, args_gv)
@@ -394,11 +455,11 @@
self._close()
def finish_and_goto(self, outputargs_gv, target):
- allocator = self.allocate_and_emit(outputargs_gv)
+ allocator = self.allocate(outputargs_gv)
min_offset = min(allocator.spill_offset, target.min_stack_offset)
- min_offset = prepare_for_jump(
- self.asm, min_offset, outputargs_gv, allocator.var2loc, target)
- self.patch_stack_adjustment(self._stack_size(min_offset))
+ allocator.spill_offset = prepare_for_jump(
+ self.insns, min_offset, outputargs_gv, allocator.var2loc, target, allocator)
+ self.emit(allocator)
self.asm.load_word(rSCRATCH, target.startaddr)
self.asm.mtctr(rSCRATCH)
self.asm.bctr()
@@ -424,15 +485,17 @@
if self.final_jump_addr != 0:
mc = self.rgenop.open_mc()
target = mc.tell()
- self.asm.mc = self.rgenop.ExistingCodeBlock(self.final_jump_addr, self.final_jump_addr+8)
+ self.asm.mc = self.rgenop.ExistingCodeBlock(
+ self.final_jump_addr, self.final_jump_addr+8)
self.asm.load_word(rSCRATCH, target)
self.asm.mc = mc
- self.emit_stack_adjustment()
+ self.final_jump_addr = 0
+ self.closed = False
return self
else:
self._open()
+ self.closed = False
self.maybe_patch_start_here()
- self.emit_stack_adjustment()
return self
def maybe_patch_start_here(self):
@@ -444,14 +507,16 @@
self.patch_start_here = 0
def pause_writing(self, args_gv):
- self.allocate_and_emit(args_gv)
+ self.initial_var2loc = self.allocate_and_emit(args_gv).var2loc
+ self.insns = []
self.final_jump_addr = self.asm.mc.tell()
+ self.closed = True
self.asm.nop()
self.asm.nop()
self.asm.mtctr(rSCRATCH)
self.asm.bctr()
self._close()
- return self
+ return self
# ----------------------------------------------------------------
# ppc-specific interface:
@@ -506,8 +571,6 @@
# save stack pointer into linkage area and set stack pointer for us.
self.asm.stwu(rSP, rSP, -minspace)
- self.emit_stack_adjustment()
-
return inputargs
def _var_offset(self, v):
@@ -535,17 +598,28 @@
self.asm.mc = None
def allocate_and_emit(self, live_vars_gv):
+ allocator = self.allocate(live_vars_gv)
+ return self.emit(allocator)
+
+ def allocate(self, live_vars_gv):
assert self.initial_var2loc is not None
allocator = RegisterAllocation(
- self.rgenop.freeregs, self.initial_var2loc, self.initial_spill_offset)
+ self.rgenop.freeregs,
+ self.initial_var2loc,
+ self.initial_spill_offset)
self.insns = allocator.allocate_for_insns(self.insns)
- #if self.insns:
- self.patch_stack_adjustment(self._stack_size(allocator.spill_offset))
+ return allocator
+
+ def emit(self, allocator):
+ if allocator.spill_offset < self.initial_spill_offset:
+ self.emit_stack_adjustment(self._stack_size(allocator.spill_offset))
for insn in self.insns:
insn.emit(self.asm)
+ for builder in allocator.builders_to_tell_spill_offset_to:
+ builder.initial_spill_offset = allocator.spill_offset
return allocator
- def emit_stack_adjustment(self):
+ def emit_stack_adjustment(self, newsize):
# the ABI requires that at all times that r1 is valid, in the
# sense that it must point to the bottom of the stack and that
# executing SP <- *(SP) repeatedly walks the stack.
@@ -560,7 +634,7 @@
# crf0 (a very small chance of being a problem)
self.stack_adj_addr = self.asm.mc.tell()
#print "emit_stack_adjustment at: ", self.stack_adj_addr
- self.asm.addi(rSCRATCH, rFP, 0) # this is the immediate that later gets patched
+ self.asm.addi(rSCRATCH, rFP, -newsize)
self.asm.subx(rSCRATCH, rSCRATCH, rSP) # rSCRATCH should now be <= 0
self.asm.beq(3) # if rSCRATCH == 0, there is no actual adjustment, so
# don't end up with the situation where *(rSP) == rSP
@@ -568,53 +642,54 @@
self.asm.stw(rFP, rSP, 0)
# branch to "here"
- def patch_stack_adjustment(self, newsize):
- if self.stack_adj_addr == 0:
- return
- #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
- # we build an addi instruction by hand here
- mc = self.asm.mc
- self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
- self.asm.addi(rSCRATCH, rFP, -newsize)
- self.asm.mc = mc
+## def patch_stack_adjustment(self, newsize):
+## if self.stack_adj_addr == 0:
+## return
+## #print "patch_stack_adjustment at:", self.stack_adj_addr, newsize
+## # we build an addi instruction by hand here
+## mc = self.asm.mc
+## self.asm.mc = self.rgenop.ExistingCodeBlock(self.stack_adj_addr, self.stack_adj_addr+4)
+## self.asm.addi(rSCRATCH, rFP, -newsize)
+## self.asm.mc = mc
- def op_int_mul(self, gv_x, gv_y):
+ def _arg_op(self, gv_arg, opcode):
gv_result = Var()
- self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.mullw,
- gv_result, [gv_x, gv_y]))
+ self.insns.append(insn.Insn_GPR__GPR(opcode, gv_result, gv_arg))
return gv_result
- def op_int_add(self, gv_x, gv_y):
+ def _arg_arg_op_with_imm(self, gv_x, gv_y, commutative, opcode, opcodei):
gv_result = Var()
if gv_y.fits_in_immediate():
self.insns.append(
- insn.Insn_GPR__GPR_IMM(RPPCAssembler.addi,
+ insn.Insn_GPR__GPR_IMM(opcodei,
gv_result, [gv_x, gv_y]))
- elif gv_x.fits_in_immediate():
+ elif gv_x.fits_in_immediate() and commutative:
self.insns.append(
- insn.Insn_GPR__GPR_IMM(RPPCAssembler.addi,
+ insn.Insn_GPR__GPR_IMM(opcodei,
gv_result, [gv_y, gv_x]))
else:
self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.add,
+ insn.Insn_GPR__GPR_GPR(opcode,
gv_result, [gv_x, gv_y]))
return gv_result
- def op_int_sub(self, gv_x, gv_y):
+ def _arg_arg_op(self, gv_x, gv_y, opcode):
gv_result = Var()
self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.sub,
+ insn.Insn_GPR__GPR_GPR(opcode,
gv_result, [gv_x, gv_y]))
return gv_result
- def op_int_floordiv(self, gv_x, gv_y):
+ def _arg_imm_op(self, gv_x, gv_imm, opcode):
gv_result = Var()
self.insns.append(
- insn.Insn_GPR__GPR_GPR(RPPCAssembler.divw,
- gv_result, [gv_x, gv_y]))
+ insn.Insn_GPR__GPR_IMM(opcode,
+ gv_result, [gv_x, gv_imm]))
return gv_result
+ def _identity(self, gv_arg):
+ return gv_arg
+
cmp2info = {
# bit-in-crf negated
'gt': ( 1, 0 ),
@@ -624,18 +699,20 @@
'eq': ( 2, 0 ),
'ne': ( 2, 1 ),
}
+
cmp2info_flipped = {
# bit-in-crf negated
- 'gt': ( 1, 1 ),
- 'lt': ( 0, 1 ),
- 'le': ( 1, 0 ),
- 'ge': ( 0, 0 ),
+ 'gt': ( 0, 0 ),
+ 'lt': ( 1, 0 ),
+ 'le': ( 0, 1 ),
+ 'ge': ( 1, 1 ),
'eq': ( 2, 0 ),
'ne': ( 2, 1 ),
}
def _compare(self, op, gv_x, gv_y):
- gv_result = Var()
+ #print "op", op
+ gv_result = ConditionVar()
if gv_y.fits_in_immediate():
self.insns.append(
insn.CMPWI(self.cmp2info[op], gv_result, [gv_x, gv_y]))
@@ -647,15 +724,67 @@
insn.CMPW(self.cmp2info[op], gv_result, [gv_x, gv_y]))
return gv_result
- def op_int_gt(self, gv_x, gv_y):
- return self._compare('gt', gv_x, gv_y)
+ def _compare_u(self, op, gv_x, gv_y):
+ gv_result = ConditionVar()
+ if gv_y.fits_in_immediate():
+ self.insns.append(
+ insn.CMPWLI(self.cmp2info[op], gv_result, [gv_x, gv_y]))
+ elif gv_x.fits_in_immediate():
+ self.insns.append(
+ insn.CMPWLI(self.cmp2info_flipped[op], gv_result, [gv_y, gv_x]))
+ else:
+ self.insns.append(
+ insn.CMPWL(self.cmp2info[op], gv_result, [gv_x, gv_y]))
+ return gv_result
+
+ def _jump(self, gv_condition, if_true, args_gv):
+ targetbuilder = self.rgenop.newbuilder()
+
+ self.insns.append(
+ insn.Jump(gv_condition, targetbuilder, if_true, args_gv))
+
+ return targetbuilder
+
+ def op_bool_not(self, gv_arg):
+ gv_result = Var()
+ self.insns.append(
+ insn.Insn_GPR__GPR_IMM(RPPCAssembler.subfi,
+ gv_result, [gv_arg, rgenop.genconst(1)]))
+ return gv_result
+
+ def op_int_is_true(self, gv_arg):
+ return self._compare('ne', gv_arg, self.rgenop.genconst(0))
+
+ def op_int_neg(self, gv_arg):
+ return self._arg_op(gv_arg, _PPC.neg)
+
+ ## op_int_neg_ovf(self, gv_arg) XXX
+
+ ## op_int_abs(self, gv_arg):
+ ## op_int_abs_ovf(self, gv_arg):
+
+ def op_int_invert(self, gv_arg):
+ return self._arg_op(gv_arg, _PPC.not_)
+
+ def op_int_add(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.add, _PPC.addi)
+
+ def op_int_sub(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.sub, _PPC.subi)
+
+ def op_int_mul(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.mullw, _PPC.mulli)
+
+ def op_int_floordiv(self, gv_x, gv_y):
+ return self._arg_arg_op(gv_x, gv_y, _PPC.divw)
+
+ ## def op_int_floordiv_zer(self, gv_x, gv_y):
+ ## def op_int_mod(self, gv_x, gv_y):
+ ## def op_int_mod_zer(self, gv_x, gv_y):
def op_int_lt(self, gv_x, gv_y):
return self._compare('lt', gv_x, gv_y)
- def op_int_ge(self, gv_x, gv_y):
- return self._compare('ge', gv_x, gv_y)
-
def op_int_le(self, gv_x, gv_y):
return self._compare('le', gv_x, gv_y)
@@ -665,34 +794,115 @@
def op_int_ne(self, gv_x, gv_y):
return self._compare('ne', gv_x, gv_y)
- def _jump(self, gv_condition, if_true, args_gv):
- targetbuilder = self.rgenop.newbuilder()
+ def op_int_gt(self, gv_x, gv_y):
+ return self._compare('gt', gv_x, gv_y)
- self.insns.append(
- insn.Jump(gv_condition, targetbuilder, if_true, args_gv))
+ def op_int_ge(self, gv_x, gv_y):
+ return self._compare('ge', gv_x, gv_y)
- return targetbuilder
+ def op_int_and(self, gv_x, gv_y):
+ return self._arg_arg_op(gv_x, gv_y, _PPC.and_)
- def op_int_is_true(self, gv_arg):
- gv_result = Var()
- self.insns.append(
- insn.CMPWI(self.cmp2info['ne'], gv_result, [gv_arg, self.rgenop.genconst(0)]))
- return gv_result
+ def op_int_or(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.or_, _PPC.ori)
- def op_bool_not(self, gv_arg):
- gv_result = Var()
- self.insns.append(
- insn.CMPWI(self.cmp2info['eq'], gv_result, [gv_arg, self.rgenop.genconst(0)]))
- return gv_result
+ def op_int_lshift(self, gv_x, gv_y):
+ # could be messy if shift is not in 0 <= ... < 32
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.slw, _PPC.slwi)
+ ## def op_int_lshift_val(self, gv_x, gv_y):
+ def op_int_rshift(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.sraw, _PPC.srawi)
+ ## def op_int_rshift_val(self, gv_x, gv_y):
- def op_int_neg(self, gv_arg):
- gv_result = Var()
- self.insns.append(
- insn.Insn_GPR__GPR(RPPCAssembler.neg, gv_result, gv_arg))
- return gv_result
+ def op_int_xor(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, True, _PPC.xor, _PPC.xori)
+
+ ## various int_*_ovfs
+
+ op_uint_is_true = op_int_is_true
+ op_uint_invert = op_int_invert
+
+ op_uint_add = op_int_add
+ op_uint_sub = op_int_sub
+ op_uint_mul = op_int_mul
+
+ def op_uint_floordiv(self, gv_x, gv_y):
+ return self._two_arg_op(gv_x, gv_y, _PPC.divwu)
+
+ ## def op_uint_floordiv_zer(self, gv_x, gv_y):
+ ## def op_uint_mod(self, gv_x, gv_y):
+ ## def op_uint_mod_zer(self, gv_x, gv_y):
+
+ def op_uint_lt(self, gv_x, gv_y):
+ return self._compare_u('lt', gv_x, gv_y)
+
+ def op_uint_le(self, gv_x, gv_y):
+ return self._compare_u('le', gv_x, gv_y)
+
+ def op_uint_eq(self, gv_x, gv_y):
+ return self._compare_u('eq', gv_x, gv_y)
+
+ def op_uint_ne(self, gv_x, gv_y):
+ return self._compare_u('ne', gv_x, gv_y)
+
+ def op_uint_gt(self, gv_x, gv_y):
+ return self._compare_u('gt', gv_x, gv_y)
+
+ def op_uint_ge(self, gv_x, gv_y):
+ return self._compare_u('ge', gv_x, gv_y)
+
+ op_uint_and = op_int_add
+ op_uint_or = op_int_or
+
+ op_uint_lshift = op_int_lshift
+ def op_uint_rshift(self, gv_x, gv_y):
+ return self._arg_arg_op_with_imm(gv_x, gv_y, False, _PPC.srw, _PPC.srwi)
+
+ ## def op_uint_lshift_val(self, gv_x, gv_y):
+ ## def op_uint_rshift(self, gv_x, gv_y):
+ ## def op_uint_rshift_val(self, gv_x, gv_y):
+
+ op_uint_xor = op_int_xor
+
+ # ... floats ...
+
+ # ... llongs, ullongs ...
+
+ # here we assume that booleans are always 1 or 0 and chars are
+ # always zero-padded.
+
+ op_cast_bool_to_int = _identity
+ op_cast_bool_to_uint = _identity
+ ## def op_cast_bool_to_float(self, gv_arg):
+ op_cast_char_to_int = _identity
+ op_cast_unichar_to_int = _identity
+ ## def op_cast_int_to_char(self, gv_arg):
+ ## def op_cast_int_to_unichar(self, gv_arg):
+ op_cast_int_to_uint = _identity
+ ## def op_cast_int_to_float(self, gv_arg):
+ ## def op_cast_int_to_longlong(self, gv_arg):
+ op_cast_uint_to_int = _identity
+ ## def op_cast_uint_to_float(self, gv_arg):
+ ## def op_cast_float_to_int(self, gv_arg):
+ ## def op_cast_float_to_uint(self, gv_arg):
+ ## def op_truncate_longlong_to_int(self, gv_arg):
+
+ # many pointer operations are genop_* special cases above
+
+ op_ptr_eq = op_int_eq
+ op_ptr_ne = op_int_ne
op_ptr_nonzero = op_int_is_true
- op_ptr_iszero = op_bool_not # for now
+ op_ptr_ne = op_int_ne
+ op_ptr_eq = op_int_eq
+
+ def op_ptr_iszero(self, gv_arg):
+ return self._compare('eq', gv_arg, self.rgenop.genconst(0))
+
+ op_cast_ptr_to_int = _identity
+ op_cast_int_to_ptr = _identity
+
+ # ... address operations ...
class RPPCGenOp(AbstractRGenOp):
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py Sat Jan 13 12:09:25 2007
@@ -1,7 +1,7 @@
import py
from pypy.jit.codegen.ppc.rgenop import RPPCGenOp
from pypy.rpython.lltypesystem import lltype
-from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests, FUNC2
+from pypy.jit.codegen.test.rgenop_tests import AbstractRGenOpTests, FUNC, FUNC2
from ctypes import cast, c_int, c_void_p, CFUNCTYPE
from pypy.jit.codegen.ppc import instruction as insn
@@ -58,6 +58,50 @@
res = fnptr(2, 1)
assert res == 100101
+ def test_flipped_cmpwi(self):
+ # return
+ # 1>x + 10*(1=x) + 1000*(1<=x) + 10000*(1==x) + 100000*(1!=x)
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "multicmp")
+ gv_one = rgenop.genconst(1)
+
+ gv_gt = builder.genop2("int_gt", gv_one, gv_x)
+ gv_lt = builder.genop2("int_lt", gv_one, gv_x)
+ gv_ge = builder.genop2("int_ge", gv_one, gv_x)
+ gv_le = builder.genop2("int_le", gv_one, gv_x)
+ gv_eq = builder.genop2("int_eq", gv_one, gv_x)
+ gv_ne = builder.genop2("int_ne", gv_one, gv_x)
+
+ gv_gt2 = gv_gt
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+
+ gv_r0 = gv_gt
+ gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
+ gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
+ gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
+ gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
+ gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
+
+ builder.finish_and_return(sigtoken, gv_r5)
+ builder.end()
+ fnptr = cast(c_void_p(gv_callable.value), CFUNCTYPE(c_int))
+
+ res = fnptr(0)
+ assert res == 100101
+
+ res = fnptr(1)
+ assert res == 11100
+
+ res = fnptr(2)
+ assert res == 101010
+
class TestRPPCGenopNoRegs(TestRPPCGenop):
RGenOp = FewRegisters
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 12:09:25 2007
@@ -389,6 +389,101 @@
return res
return fact_runner
+def make_func_calling_pause(rgenop):
+ # def f(x):
+ # if x > 0:
+ # return x
+ # else:
+ # return -x
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_f, [gv_x] = rgenop.newgraph(sigtoken, "abs")
+
+ gv_cond = builder.genop2("int_gt", gv_x, rgenop.genconst(0))
+
+ targetbuilder = builder.jump_if_false(gv_cond, [gv_x])
+
+ builder = builder.pause_writing([gv_x])
+
+ targetbuilder.start_writing()
+ gv_negated = targetbuilder.genop1("int_neg", gv_x)
+ targetbuilder.finish_and_return(sigtoken, gv_negated)
+
+ builder.start_writing()
+ builder.finish_and_return(sigtoken, gv_x)
+
+ return gv_f
+
+def get_func_calling_pause_runner(RGenOp):
+ def runner(x):
+ rgenop = RGenOp()
+ gv_abs = make_func_calling_pause(rgenop)
+ myabs = gv_abs.revealconst(lltype.Ptr(FUNC))
+ res = myabs(x)
+ keepalive_until_here(rgenop) # to keep the code blocks alive
+ return res
+ return runner
+
+def make_longwinded_and(rgenop):
+ # def f(y): return 2 <= y <= 4
+ # but more like this:
+ # def f(y)
+ # x = 2 <= y
+ # if x:
+ # x = y <= 4
+ # if x:
+ # return 1
+ # else:
+ # return 0
+
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "abs")
+
+ gv_x = builder.genop2("int_le", rgenop.genconst(2), gv_y)
+
+ false_builder = builder.jump_if_false(gv_x, [gv_x])
+
+ gv_x2 = builder.genop2("int_le", gv_y, rgenop.genconst(4))
+
+ args_gv = [gv_x2]
+ label = builder.enter_next_block([signed_kind], args_gv)
+ [gv_x2] = args_gv
+
+ return_false_builder = builder.jump_if_false(gv_x2, [])
+
+ builder.finish_and_return(sigtoken, rgenop.genconst(1))
+
+ false_builder.start_writing()
+ false_builder.finish_and_goto([gv_x], label)
+
+ return_false_builder.start_writing()
+ return_false_builder.finish_and_return(sigtoken, rgenop.genconst(0))
+
+ return gv_f
+
+def make_condition_result_cross_link(rgenop):
+
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "foo")
+
+ gv_result = builder.genop2("int_eq", gv_y, rgenop.genconst(0))
+ target1 = builder.jump_if_false(gv_result, [gv_result])
+
+ builder.finish_and_return(sigtoken, rgenop.genconst(1))
+
+ target1.start_writing()
+ target2 = target1.jump_if_false(gv_result, [])
+
+ # this return should be unreachable:
+ target1.finish_and_return(sigtoken, rgenop.genconst(2))
+
+ target2.start_writing()
+ target2.finish_and_return(sigtoken, rgenop.genconst(3))
+
+ return gv_f
+
class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
RGenOp = None
@@ -586,3 +681,54 @@
res = fn(11)
assert res == 39916800
+ def test_calling_pause_direct(self):
+ rgenop = self.RGenOp()
+ gv_abs = make_func_calling_pause(rgenop)
+ fnptr = self.cast(gv_abs, 1)
+ res = fnptr(2)
+ assert res == 2
+ res = fnptr(-42)
+ assert res == 42
+
+ def test_calling_pause_compile(self):
+ fn = self.compile(get_func_calling_pause_runner(self.RGenOp), [int])
+ res = fn(2)
+ assert res == 2
+ res = fn(-72)
+ assert res == 72
+
+ def test_longwinded_and_direct(self):
+ rgenop = self.RGenOp()
+ gv_fn = make_longwinded_and(rgenop)
+ fnptr = self.cast(gv_fn, 1)
+
+ print map(fnptr, range(6))
+
+ res = fnptr(1)
+ assert res == 0
+
+ res = fnptr(2)
+ assert res == 1
+
+ res = fnptr(3)
+ assert res == 1
+
+ res = fnptr(4)
+ assert res == 1
+
+ res = fnptr(5)
+ assert res == 0
+
+ def test_condition_result_cross_link_direct(self):
+ rgenop = self.RGenOp()
+ gv_fn = make_condition_result_cross_link(rgenop)
+ fnptr = self.cast(gv_fn, 1)
+
+ res = fnptr(-1)
+ assert res == 3
+
+ res = fnptr(0)
+ assert res == 1
+
+ res = fnptr(1)
+ assert res == 3
From mwh at codespeak.net Sat Jan 13 13:37:09 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Sat, 13 Jan 2007 13:37:09 +0100 (CET)
Subject: [pypy-svn] r36644 - pypy/extradoc/sprintinfo/leysin-winter-2007
Message-ID: <20070113123709.602B710087@code0.codespeak.net>
Author: mwh
Date: Sat Jan 13 13:37:01 2007
New Revision: 36644
Modified:
pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
Log:
foodmoney update
Modified: pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt
==============================================================================
--- pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt (original)
+++ pypy/extradoc/sprintinfo/leysin-winter-2007/foodmoney.txt Sat Jan 13 13:37:01 2007
@@ -1,16 +1,16 @@
-Armin Rigo -10 -8 -8 -8
-Anders Chrigstroem -10 -8 -8 -8
-Samuele Pedroni -10 -8 -8 -8
-Michael Hudson -10 -8 -8 -8
+Armin Rigo -10 -8 -8 -8 -8
+Anders Chrigstroem -10 -8 -8 -8 -8
+Samuele Pedroni -10 -8 -8 -8 -8
+Michael Hudson -10 -8 -8 -8 +84 -8
Niko Matsakis -8
-Antonio Cuni -10 -8 +8 -8 -8
-Maciej Fijalkowski -10 -8 +110 -8 -8
-Eric van Riet Paap -8 -8
-Jacob Hallen -10 -8 -8 -8
-Laura Creighton -10 -8 -8 -8
+Antonio Cuni -10 -8 +8 -8 -8 -8
+Maciej Fijalkowski -10 -8 +110 -8 -8 -8
+Eric van Riet Paap -8 -8 -8
+Jacob Hallen -10 -8 -8 -8 -8
+Laura Creighton -10 -8 -8 -8 -8
Holger Krekel -10 -8 -8
-Carl Friedrich Bolz -10 -8 -8 -8
-Guido Wesdorp -10 +134 -8 -8 +125
-Leonardo Santagada -10 -8 -8 -8
+Carl Friedrich Bolz -10 -8 -8 -8 -8
+Guido Wesdorp -10 +134 -8 -8 +125 -8
+Leonardo Santagada -10 -8 -8 -8 -8
Alexandre Fayolle -10 -8 +124 -8 -8
Sylvain Th?nault -10 -8 -8 -8
From mwh at codespeak.net Sat Jan 13 14:03:14 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Sat, 13 Jan 2007 14:03:14 +0100 (CET)
Subject: [pypy-svn] r36649 - in pypy/dist/pypy/jit/codegen: ppc/test test
Message-ID: <20070113130314.AB8D710088@code0.codespeak.net>
Author: mwh
Date: Sat Jan 13 14:03:13 2007
New Revision: 36649
Modified:
pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
move more tests from ppc/test/test_rgenop to test/rgenop_tests for added fun
for arigo.
Modified: pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/ppc/test/test_rgenop.py Sat Jan 13 14:03:13 2007
@@ -15,93 +15,6 @@
class TestRPPCGenop(AbstractRGenOpTests):
RGenOp = RPPCGenOp
- def test_multiple_cmps(self):
- # return x>y + 10*x=y + 10000*x==y + 100000*x!=y
- rgenop = self.RGenOp()
- signed_kind = rgenop.kindToken(lltype.Signed)
- sigtoken = rgenop.sigToken(FUNC2)
- builder, gv_callable, [gv_x, gv_y] = rgenop.newgraph(sigtoken,
- "multicmp")
-
- args_gv = [gv_x, gv_y]
- builder.enter_next_block([signed_kind, signed_kind], args_gv)
- [gv_x, gv_y] = args_gv
-
- gv_gt = builder.genop2("int_gt", gv_x, gv_y)
- gv_lt = builder.genop2("int_lt", gv_x, gv_y)
- gv_ge = builder.genop2("int_ge", gv_x, gv_y)
- gv_le = builder.genop2("int_le", gv_x, gv_y)
- gv_eq = builder.genop2("int_eq", gv_x, gv_y)
- gv_ne = builder.genop2("int_ne", gv_x, gv_y)
-
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
-
- gv_r0 = gv_gt
- gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
- gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
- gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
- gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
- gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
-
- builder.finish_and_return(sigtoken, gv_r5)
- builder.end()
- fnptr = cast(c_void_p(gv_callable.value), CFUNCTYPE(c_int, c_int))
- res = fnptr(1, 2)
- assert res == 101010
- res = fnptr(1, 1)
- assert res == 11100
- res = fnptr(2, 1)
- assert res == 100101
-
- def test_flipped_cmpwi(self):
- # return
- # 1>x + 10*(1=x) + 1000*(1<=x) + 10000*(1==x) + 100000*(1!=x)
- rgenop = self.RGenOp()
- signed_kind = rgenop.kindToken(lltype.Signed)
- sigtoken = rgenop.sigToken(FUNC)
- builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
- "multicmp")
- gv_one = rgenop.genconst(1)
-
- gv_gt = builder.genop2("int_gt", gv_one, gv_x)
- gv_lt = builder.genop2("int_lt", gv_one, gv_x)
- gv_ge = builder.genop2("int_ge", gv_one, gv_x)
- gv_le = builder.genop2("int_le", gv_one, gv_x)
- gv_eq = builder.genop2("int_eq", gv_one, gv_x)
- gv_ne = builder.genop2("int_ne", gv_one, gv_x)
-
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
-
- gv_r0 = gv_gt
- gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
- gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
- gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
- gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
- gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
-
- builder.finish_and_return(sigtoken, gv_r5)
- builder.end()
- fnptr = cast(c_void_p(gv_callable.value), CFUNCTYPE(c_int))
-
- res = fnptr(0)
- assert res == 100101
-
- res = fnptr(1)
- assert res == 11100
-
- res = fnptr(2)
- assert res == 101010
-
class TestRPPCGenopNoRegs(TestRPPCGenop):
RGenOp = FewRegisters
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 14:03:13 2007
@@ -661,3 +661,91 @@
res = fnptr(1)
assert res == 3
+
+
+ def test_multiple_cmps(self):
+ # return x>y + 10*x=y + 10000*x==y + 100000*x!=y
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC2)
+ builder, gv_callable, [gv_x, gv_y] = rgenop.newgraph(sigtoken,
+ "multicmp")
+
+ args_gv = [gv_x, gv_y]
+ builder.enter_next_block([signed_kind, signed_kind], args_gv)
+ [gv_x, gv_y] = args_gv
+
+ gv_gt = builder.genop2("int_gt", gv_x, gv_y)
+ gv_lt = builder.genop2("int_lt", gv_x, gv_y)
+ gv_ge = builder.genop2("int_ge", gv_x, gv_y)
+ gv_le = builder.genop2("int_le", gv_x, gv_y)
+ gv_eq = builder.genop2("int_eq", gv_x, gv_y)
+ gv_ne = builder.genop2("int_ne", gv_x, gv_y)
+
+ gv_gt2 = gv_gt
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+
+ gv_r0 = gv_gt
+ gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
+ gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
+ gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
+ gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
+ gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
+
+ builder.finish_and_return(sigtoken, gv_r5)
+ builder.end()
+ fnptr = self.cast(gv_callable, 2)
+ res = fnptr(1, 2)
+ assert res == 101010
+ res = fnptr(1, 1)
+ assert res == 11100
+ res = fnptr(2, 1)
+ assert res == 100101
+
+ def test_flipped_cmp_with_immediate(self):
+ # return
+ # 1>x + 10*(1=x) + 1000*(1<=x) + 10000*(1==x) + 100000*(1!=x)
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "multicmp")
+ gv_one = rgenop.genconst(1)
+
+ gv_gt = builder.genop2("int_gt", gv_one, gv_x)
+ gv_lt = builder.genop2("int_lt", gv_one, gv_x)
+ gv_ge = builder.genop2("int_ge", gv_one, gv_x)
+ gv_le = builder.genop2("int_le", gv_one, gv_x)
+ gv_eq = builder.genop2("int_eq", gv_one, gv_x)
+ gv_ne = builder.genop2("int_ne", gv_one, gv_x)
+
+ gv_gt2 = gv_gt
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+
+ gv_r0 = gv_gt
+ gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
+ gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
+ gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
+ gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
+ gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
+
+ builder.finish_and_return(sigtoken, gv_r5)
+ builder.end()
+ fnptr = self.cast(gv_callable, 1)
+
+ res = fnptr(0)
+ assert res == 100101
+
+ res = fnptr(1)
+ assert res == 11100
+
+ res = fnptr(2)
+ assert res == 101010
From arigo at codespeak.net Sat Jan 13 14:04:50 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 14:04:50 +0100 (CET)
Subject: [pypy-svn] r36650 - in pypy/branch/i386-regalloc/pypy/jit/codegen:
ppc/test test
Message-ID: <20070113130450.0CEB910087@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 14:04:49 2007
New Revision: 36650
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
svn merge -r36634:36649 http://codespeak.net/svn/pypy/dist/pypy/jit/codegen
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/ppc/test/test_rgenop.py Sat Jan 13 14:04:49 2007
@@ -15,93 +15,6 @@
class TestRPPCGenop(AbstractRGenOpTests):
RGenOp = RPPCGenOp
- def test_multiple_cmps(self):
- # return x>y + 10*x=y + 10000*x==y + 100000*x!=y
- rgenop = self.RGenOp()
- signed_kind = rgenop.kindToken(lltype.Signed)
- sigtoken = rgenop.sigToken(FUNC2)
- builder, gv_callable, [gv_x, gv_y] = rgenop.newgraph(sigtoken,
- "multicmp")
-
- args_gv = [gv_x, gv_y]
- builder.enter_next_block([signed_kind, signed_kind], args_gv)
- [gv_x, gv_y] = args_gv
-
- gv_gt = builder.genop2("int_gt", gv_x, gv_y)
- gv_lt = builder.genop2("int_lt", gv_x, gv_y)
- gv_ge = builder.genop2("int_ge", gv_x, gv_y)
- gv_le = builder.genop2("int_le", gv_x, gv_y)
- gv_eq = builder.genop2("int_eq", gv_x, gv_y)
- gv_ne = builder.genop2("int_ne", gv_x, gv_y)
-
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
-
- gv_r0 = gv_gt
- gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
- gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
- gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
- gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
- gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
-
- builder.finish_and_return(sigtoken, gv_r5)
- builder.end()
- fnptr = cast(c_void_p(gv_callable.value), CFUNCTYPE(c_int, c_int))
- res = fnptr(1, 2)
- assert res == 101010
- res = fnptr(1, 1)
- assert res == 11100
- res = fnptr(2, 1)
- assert res == 100101
-
- def test_flipped_cmpwi(self):
- # return
- # 1>x + 10*(1=x) + 1000*(1<=x) + 10000*(1==x) + 100000*(1!=x)
- rgenop = self.RGenOp()
- signed_kind = rgenop.kindToken(lltype.Signed)
- sigtoken = rgenop.sigToken(FUNC)
- builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
- "multicmp")
- gv_one = rgenop.genconst(1)
-
- gv_gt = builder.genop2("int_gt", gv_one, gv_x)
- gv_lt = builder.genop2("int_lt", gv_one, gv_x)
- gv_ge = builder.genop2("int_ge", gv_one, gv_x)
- gv_le = builder.genop2("int_le", gv_one, gv_x)
- gv_eq = builder.genop2("int_eq", gv_one, gv_x)
- gv_ne = builder.genop2("int_ne", gv_one, gv_x)
-
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
-
- gv_r0 = gv_gt
- gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
- gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
- gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
- gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
- gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
-
- builder.finish_and_return(sigtoken, gv_r5)
- builder.end()
- fnptr = cast(c_void_p(gv_callable.value), CFUNCTYPE(c_int))
-
- res = fnptr(0)
- assert res == 100101
-
- res = fnptr(1)
- assert res == 11100
-
- res = fnptr(2)
- assert res == 101010
-
class TestRPPCGenopNoRegs(TestRPPCGenop):
RGenOp = FewRegisters
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 14:04:49 2007
@@ -732,3 +732,91 @@
res = fnptr(1)
assert res == 3
+
+
+ def test_multiple_cmps(self):
+ # return x>y + 10*x=y + 10000*x==y + 100000*x!=y
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC2)
+ builder, gv_callable, [gv_x, gv_y] = rgenop.newgraph(sigtoken,
+ "multicmp")
+
+ args_gv = [gv_x, gv_y]
+ builder.enter_next_block([signed_kind, signed_kind], args_gv)
+ [gv_x, gv_y] = args_gv
+
+ gv_gt = builder.genop2("int_gt", gv_x, gv_y)
+ gv_lt = builder.genop2("int_lt", gv_x, gv_y)
+ gv_ge = builder.genop2("int_ge", gv_x, gv_y)
+ gv_le = builder.genop2("int_le", gv_x, gv_y)
+ gv_eq = builder.genop2("int_eq", gv_x, gv_y)
+ gv_ne = builder.genop2("int_ne", gv_x, gv_y)
+
+ gv_gt2 = gv_gt
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+
+ gv_r0 = gv_gt
+ gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
+ gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
+ gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
+ gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
+ gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
+
+ builder.finish_and_return(sigtoken, gv_r5)
+ builder.end()
+ fnptr = self.cast(gv_callable, 2)
+ res = fnptr(1, 2)
+ assert res == 101010
+ res = fnptr(1, 1)
+ assert res == 11100
+ res = fnptr(2, 1)
+ assert res == 100101
+
+ def test_flipped_cmp_with_immediate(self):
+ # return
+ # 1>x + 10*(1=x) + 1000*(1<=x) + 10000*(1==x) + 100000*(1!=x)
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "multicmp")
+ gv_one = rgenop.genconst(1)
+
+ gv_gt = builder.genop2("int_gt", gv_one, gv_x)
+ gv_lt = builder.genop2("int_lt", gv_one, gv_x)
+ gv_ge = builder.genop2("int_ge", gv_one, gv_x)
+ gv_le = builder.genop2("int_le", gv_one, gv_x)
+ gv_eq = builder.genop2("int_eq", gv_one, gv_x)
+ gv_ne = builder.genop2("int_ne", gv_one, gv_x)
+
+ gv_gt2 = gv_gt
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+
+ gv_r0 = gv_gt
+ gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
+ gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
+ gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
+ gv_r4 = builder.genop2("int_add", gv_r3, gv_eq2)
+ gv_r5 = builder.genop2("int_add", gv_r4, gv_ne2)
+
+ builder.finish_and_return(sigtoken, gv_r5)
+ builder.end()
+ fnptr = self.cast(gv_callable, 1)
+
+ res = fnptr(0)
+ assert res == 100101
+
+ res = fnptr(1)
+ assert res == 11100
+
+ res = fnptr(2)
+ assert res == 101010
From arigo at codespeak.net Sat Jan 13 14:49:24 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 14:49:24 +0100 (CET)
Subject: [pypy-svn] r36653 - pypy/dist/pypy/jit/codegen/test
Message-ID: <20070113134924.F2DA410083@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 14:49:23 2007
New Revision: 36653
Modified:
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
Fix the test.
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 14:49:23 2007
@@ -379,7 +379,7 @@
# else:
# return 0
- signed_kind = rgenop.kindToken(lltype.Signed)
+ bool_kind = rgenop.kindToken(lltype.Bool)
sigtoken = rgenop.sigToken(FUNC)
builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "abs")
@@ -390,7 +390,7 @@
gv_x2 = builder.genop2("int_le", gv_y, rgenop.genconst(4))
args_gv = [gv_x2]
- label = builder.enter_next_block([signed_kind], args_gv)
+ label = builder.enter_next_block([bool_kind], args_gv)
[gv_x2] = args_gv
return_false_builder = builder.jump_if_false(gv_x2, [])
@@ -631,8 +631,6 @@
gv_fn = make_longwinded_and(rgenop)
fnptr = self.cast(gv_fn, 1)
- print map(fnptr, range(6))
-
res = fnptr(1)
assert res == 0
From antocuni at codespeak.net Sat Jan 13 14:57:21 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 13 Jan 2007 14:57:21 +0100 (CET)
Subject: [pypy-svn] r36654 - in pypy/dist/pypy/translator: . backendopt
backendopt/test
Message-ID: <20070113135721.CFE8E10083@code0.codespeak.net>
Author: antocuni
Date: Sat Jan 13 14:57:20 2007
New Revision: 36654
Modified:
pypy/dist/pypy/translator/backendopt/all.py
pypy/dist/pypy/translator/backendopt/checkvirtual.py
pypy/dist/pypy/translator/backendopt/inline.py
pypy/dist/pypy/translator/backendopt/test/test_all.py
pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py
pypy/dist/pypy/translator/backendopt/test/test_inline.py
pypy/dist/pypy/translator/backendopt/test/test_malloc.py
pypy/dist/pypy/translator/driver.py
Log:
Inline oosends we can dispatch at compile-time because they call
non-virtual methods.
Make backend_optimizations() always call check_virtual_methods when
using ootypesystem.
Make ootype.ROOT the default Instance where to start from when
checking virtual methods.
Modified: pypy/dist/pypy/translator/backendopt/all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/all.py (original)
+++ pypy/dist/pypy/translator/backendopt/all.py Sat Jan 13 14:57:20 2007
@@ -10,6 +10,7 @@
from pypy.translator.backendopt.mallocprediction import clever_inlining_and_malloc_removal
from pypy.translator.backendopt.removeassert import remove_asserts
from pypy.translator.backendopt.support import log
+from pypy.translator.backendopt.checkvirtual import check_virtual_methods
from pypy.objspace.flow.model import checkgraph
def backend_optimizations(translator, graphs=None, secondary=False, **kwds):
@@ -31,6 +32,9 @@
if config.raisingop2direct_call:
raisingop2direct_call(translator, graphs)
+ if translator.rtyper.type_system.name == 'ootypesystem':
+ check_virtual_methods()
+
# remove obvious no-ops
for graph in graphs:
removenoops.remove_same_as(graph)
Modified: pypy/dist/pypy/translator/backendopt/checkvirtual.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/checkvirtual.py (original)
+++ pypy/dist/pypy/translator/backendopt/checkvirtual.py Sat Jan 13 14:57:20 2007
@@ -7,7 +7,9 @@
non-virtual calls, such as JVM).
"""
-def check_virtual_methods(INSTANCE, super_methods = {}):
+from pypy.rpython.ootypesystem import ootype
+
+def check_virtual_methods(INSTANCE=ootype.ROOT, super_methods = {}):
my_methods = super_methods.copy()
for name, method in INSTANCE._methods.iteritems():
method._virtual = False
Modified: pypy/dist/pypy/translator/backendopt/inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/inline.py Sat Jan 13 14:57:20 2007
@@ -22,6 +22,16 @@
class CannotInline(Exception):
pass
+def get_meth_from_oosend(op):
+ method_name = op.args[0].value
+ INSTANCE = op.args[1].concretetype
+ _, meth = INSTANCE._lookup(op.args[0].value)
+ virtual = getattr(meth, '_virtual', True)
+ if virtual:
+ return None
+ else:
+ return meth
+
def collect_called_graphs(graph, translator):
graphs_or_something = {}
for block in graph.iterblocks():
@@ -40,15 +50,23 @@
for graph in graphs:
graphs_or_something[graph] = True
if op.opname == 'oosend':
- graphs_or_something[op.args[0]] = True # XXX?
+ meth = get_meth_from_oosend(op)
+ key = getattr(meth, 'graph', op.args[0])
+ graphs_or_something[key] = True
return graphs_or_something
def iter_callsites(graph, calling_what):
for block in graph.iterblocks():
for i, op in enumerate(block.operations):
- if not op.opname == "direct_call":
+ if op.opname == "direct_call":
+ funcobj = get_funcobj(op.args[0].value)
+ elif op.opname == "oosend":
+ funcobj = get_meth_from_oosend(op)
+ if funcobj is None:
+ continue # cannot inline virtual methods
+ else:
continue
- funcobj = get_funcobj(op.args[0].value)
+
graph = getattr(funcobj, 'graph', None)
# accept a function or a graph as 'inline_func'
if (graph is calling_what or
@@ -178,11 +196,18 @@
self.cleanup()
return count
+ def get_graph_from_op(self, op):
+ assert op.opname in ('direct_call', 'oosend')
+ if op.opname == 'direct_call':
+ return get_funcobj(self.op.args[0].value).graph
+ else:
+ return get_meth_from_oosend(op).graph
+
def inline_once(self, block, index_operation):
self.varmap = {}
self._copied_blocks = {}
self.op = block.operations[index_operation]
- self.graph_to_inline = get_funcobj(self.op.args[0].value).graph
+ self.graph_to_inline = self.get_graph_from_op(self.op)
self.exception_guarded = False
if (block.exitswitch == c_last_exception and
index_operation == len(block.operations) - 1):
@@ -201,9 +226,14 @@
def search_for_calls(self, block):
d = {}
for i, op in enumerate(block.operations):
- if not op.opname == "direct_call":
+ if op.opname == "direct_call":
+ funcobj = get_funcobj(op.args[0].value)
+ elif op.opname == "oosend":
+ funcobj = get_meth_from_oosend(op)
+ if funcobj is None:
+ continue
+ else:
continue
- funcobj = get_funcobj(op.args[0].value)
graph = getattr(funcobj, 'graph', None)
# accept a function or a graph as 'inline_func'
if (graph is self.inline_func or
@@ -565,9 +595,13 @@
'dont_inline', False):
continue
result.append((parentgraph, graph))
+ if op.opname == "oosend":
+ meth = get_meth_from_oosend(op)
+ graph = getattr(meth, 'graph', None)
+ if graph is not None:
+ result.append((parentgraph, graph))
return result
-
-
+
def instrument_inline_candidates(graphs, multiplier):
threshold = BASE_INLINE_THRESHOLD * multiplier
cache = {None: False}
Modified: pypy/dist/pypy/translator/backendopt/test/test_all.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_all.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_all.py Sat Jan 13 14:57:20 2007
@@ -217,5 +217,3 @@
type_system = 'ootype'
check_malloc_removed = OOTypeMallocRemovalTest.check_malloc_removed
- def test_big(self):
- py.test.skip('FIXME! It should pass as long as oosend is inlined')
Modified: pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_checkvirtual.py Sat Jan 13 14:57:20 2007
@@ -6,7 +6,7 @@
A = Instance("A", ROOT)
addMethods(A, {"foo": meth(Meth([], Void))})
- check_virtual_methods(ROOT)
+ check_virtual_methods()
assert A._methods["foo"]._virtual == False
def test_checkvirtual_simple():
@@ -18,7 +18,7 @@
addMethods(B, {"foo": meth(Meth([], Void))})
- check_virtual_methods(ROOT)
+ check_virtual_methods()
assert A._methods["foo"]._virtual == True
assert A._methods["bar"]._virtual == False
assert B._methods["foo"]._virtual == False
@@ -33,7 +33,7 @@
addMethods(C, {"foo": meth(Meth([], Void))})
- check_virtual_methods(ROOT)
+ check_virtual_methods()
assert A._methods["foo"]._virtual == True
assert A._methods["bar"]._virtual == False
assert "foo" not in B._methods
@@ -49,7 +49,7 @@
addMethods(B1, {"foo": meth(Meth([], Void))})
- check_virtual_methods(ROOT)
+ check_virtual_methods()
assert A._methods["foo"]._virtual == True
assert A._methods["bar"]._virtual == False
assert B1._methods["foo"]._virtual == False
Modified: pypy/dist/pypy/translator/backendopt/test/test_inline.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_inline.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_inline.py Sat Jan 13 14:57:20 2007
@@ -9,6 +9,7 @@
from pypy.translator.backendopt.inline import collect_called_graphs
from pypy.translator.backendopt.inline import measure_median_execution_cost
from pypy.translator.backendopt.inline import instrument_inline_candidates
+from pypy.translator.backendopt.checkvirtual import check_virtual_methods
from pypy.translator.translator import TranslationContext, graphof
from pypy.rpython.llinterp import LLInterpreter
from pypy.rpython.test.tool import LLRtypeMixin, OORtypeMixin
@@ -84,8 +85,11 @@
return interp.eval_graph(graphof(t, entry), args)
return eval_func
- def check_auto_inlining(self, func, sig, multiplier=None, call_count_check=False):
+ def check_auto_inlining(self, func, sig, multiplier=None, call_count_check=False,
+ checkvirtual=False):
t = self.translate(func, sig)
+ if checkvirtual:
+ check_virtual_methods()
if option.view:
t.view()
# inline!
@@ -585,3 +589,50 @@
expected = fn(0)
res = eval_func([0])
assert res == expected
+
+ def test_oosend(self):
+ class A:
+ def foo(self, x):
+ return x
+ def fn(x):
+ a = A()
+ return a.foo(x)
+
+ eval_func, t = self.check_auto_inlining(fn, [int], checkvirtual=True)
+ expected = fn(42)
+ res = eval_func([42])
+ assert res == expected
+
+ def test_not_inline_oosend(self):
+ class A:
+ def foo(self, x):
+ return x
+ class B(A):
+ def foo(self, x):
+ return x+1
+
+ def fn(flag, x):
+ if flag:
+ obj = A()
+ else:
+ obj = B()
+ return obj.foo(x)
+
+ eval_func, t = self.check_auto_inlining(fn, [bool, int], checkvirtual=True)
+ expected = fn(True, 42)
+ res = eval_func([True, 42])
+ assert res == expected
+
+ def test_classattr(self):
+ class A:
+ attr = 666
+ class B(A):
+ attr = 42
+ def fn5():
+ b = B()
+ return b.attr
+
+ eval_func, t = self.check_auto_inlining(fn5, [], checkvirtual=True)
+ res = eval_func([])
+ assert res == 42
+
Modified: pypy/dist/pypy/translator/backendopt/test/test_malloc.py
==============================================================================
--- pypy/dist/pypy/translator/backendopt/test/test_malloc.py (original)
+++ pypy/dist/pypy/translator/backendopt/test/test_malloc.py Sat Jan 13 14:57:20 2007
@@ -104,7 +104,6 @@
self.check(fn4, [int], [42], 42)
def test_fn5(self):
- self._skip_oo('It will work as soon as trivial oosend are inlined')
class A:
attr = 666
class B(A):
@@ -352,3 +351,9 @@
return x.foo
self.check(fn, [], [], 42)
+ def test_fn5(self):
+ # don't test this in ootype because the class attribute access
+ # is turned into an oosend which prevents malloc removal to
+ # work unless we inline first. See test_classattr in
+ # test_inline.py
+ pass
Modified: pypy/dist/pypy/translator/driver.py
==============================================================================
--- pypy/dist/pypy/translator/driver.py (original)
+++ pypy/dist/pypy/translator/driver.py Sat Jan 13 14:57:20 2007
@@ -355,9 +355,6 @@
heap2stack=False,
clever_malloc_removal=False)
if self.config.translation.backend == 'cli':
- from pypy.translator.backendopt.checkvirtual import check_virtual_methods
- from pypy.rpython.ootypesystem import ootype
- check_virtual_methods(ootype.ROOT)
opt['merge_if_blocks'] = True
opt['inline_threshold'] = 1
opt['mallocs'] = True
From arigo at codespeak.net Sat Jan 13 14:58:15 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 14:58:15 +0100 (CET)
Subject: [pypy-svn] r36655 - pypy/branch/i386-regalloc/pypy/jit/codegen/test
Message-ID: <20070113135815.C368E10087@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 14:58:14 2007
New Revision: 36655
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
svn merge -r36649:36654 http://codespeak.net/svn/pypy/dist/pypy/jit/codegen
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 14:58:14 2007
@@ -436,7 +436,7 @@
# else:
# return 0
- signed_kind = rgenop.kindToken(lltype.Signed)
+ bool_kind = rgenop.kindToken(lltype.Bool)
sigtoken = rgenop.sigToken(FUNC)
builder, gv_f, [gv_y] = rgenop.newgraph(sigtoken, "abs")
@@ -447,7 +447,7 @@
gv_x2 = builder.genop2("int_le", gv_y, rgenop.genconst(4))
args_gv = [gv_x2]
- label = builder.enter_next_block([signed_kind], args_gv)
+ label = builder.enter_next_block([bool_kind], args_gv)
[gv_x2] = args_gv
return_false_builder = builder.jump_if_false(gv_x2, [])
@@ -702,8 +702,6 @@
gv_fn = make_longwinded_and(rgenop)
fnptr = self.cast(gv_fn, 1)
- print map(fnptr, range(6))
-
res = fnptr(1)
assert res == 0
From arigo at codespeak.net Sat Jan 13 14:59:37 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 14:59:37 +0100 (CET)
Subject: [pypy-svn] r36656 - in
pypy/branch/i386-regalloc/pypy/jit/codegen/i386: . test
Message-ID: <20070113135937.92A4910083@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 14:59:35 2007
New Revision: 36656
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386setup.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_auto_encoding.py
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_ri386.py
Log:
(Disabled) attempt at introducing a generic operation called 'Jcond()'.
Same for SETcond() and CMOVcond().
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386setup.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386setup.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/ri386setup.py Sat Jan 13 14:59:35 2007
@@ -111,6 +111,14 @@
lines.append('builder.write(packimm32(offset))')
return False
+##class conditioncode(operand):
+## def __init__(self):
+## pass
+## def eval(self, lines, has_orbyte):
+## assert not has_orbyte, "malformed bytecode"
+## lines.append('orbyte = arg1.value')
+## return True
+
def consolidate(code1):
for i in range(len(code1)-1, 0, -1):
@@ -463,6 +471,17 @@
define_cond('CMOV',0,(REG,MODRM),['\x0F', None,'\x40', register(1,8), modrm(2)])
# note: CMOVxx are Pentium-class instructions, unknown to the 386 and 486
+##Jcond = Instruction()
+##Jcond.mode2( IMM8, REL32, ['\x0F', conditioncode(),'\x80', relative(2)])
+
+##SETcond = Instruction()
+##SETcond.mode2(IMM8, MODRM8, ['\x0F', conditioncode(),'\x90', orbyte(0<<3),
+## modrm(2,'b')])
+
+##CMOVcond = Instruction()
+##CMOVcond.mode3(IMM8,REG,MODRM, ['\x0F', conditioncode(),'\x40', register(2,8),
+## modrm(3)])
+
all_instructions = {}
for key, value in globals().items():
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_auto_encoding.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_auto_encoding.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_auto_encoding.py Sat Jan 13 14:59:35 2007
@@ -211,7 +211,7 @@
if instrname in ('MOVZX', 'MOVSX'):
if args[1][1].width == 4:
return []
- if instrname == 'o16':
+ if instrname == 'o16' or instrname.endswith('cond'):
return []
return [args]
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_ri386.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_ri386.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_ri386.py Sat Jan 13 14:59:35 2007
@@ -75,6 +75,19 @@
yield check, '\xE8\x11\x00\x00\x00', 'CALL', rel32(22)
+##def test_conditional():
+## """Compare the encoding for the instructions JE, JAE, JC etc.,
+## with the encoding for the 'Jcond' pseudo-instruction.
+## """
+## def check(insn, *args):
+## from pypy.jit.codegen.i386.ri386setup import Conditions
+## for cond, value in Conditions.items():
+## s1 = CodeBuilder()
+## getattr(s1, insn+cond)(*args)
+## s2 = CodeBuilder()
+## getattr(s2, insn+'cond')(imm8(value), *args)
+
+
def test_translate():
from pypy.rpython.test.test_llinterp import interpret
From arigo at codespeak.net Sat Jan 13 15:00:01 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 15:00:01 +0100 (CET)
Subject: [pypy-svn] r36657 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113140001.29A8310088@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 14:59:59 2007
New Revision: 36657
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Fix condition code handling over links. More tests pass.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 14:59:59 2007
@@ -1,4 +1,4 @@
-from pypy.rlib.objectmodel import specialize
+from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
from pypy.jit.codegen.model import GenVar, GenConst, CodeGenSwitch
@@ -32,13 +32,19 @@
self.x = x
def allocate(self, allocator):
allocator.using(self.x)
-## def generate(self, allocator):
-## try:
-## loc = allocator.var2loc[self]
-## except KeyError:
-## return # simple operation whose result is not used anyway
-## op = allocator.load_location_with(loc, self.x)
-## self.emit(allocator.mc, op)
+
+class UnaryOp(Op1):
+ def generate(self, allocator):
+ try:
+ loc = allocator.var2loc[self]
+ except KeyError:
+ return # simple operation whose result is not used anyway
+ op = allocator.load_location_with(loc, self.x)
+ self.emit(allocator.mc, op)
+
+class OpIntNeg(UnaryOp):
+ opname = 'int_neg'
+ emit = staticmethod(I386CodeBuilder.NEG)
class OpSameAs(Op1):
clobbers_cc = False
@@ -65,19 +71,21 @@
class OpIntIsTrue(OpCompare1):
opname = 'int_is_true'
- cc_result = I386CodeBuilder.JNE
+ cc_result = Conditions['NE']
@staticmethod
def emit(mc, x):
mc.CMP(x, imm8(0))
class Op2(Operation):
- commutative = False
def __init__(self, x, y):
self.x = x
self.y = y
def allocate(self, allocator):
allocator.using(self.x)
allocator.using(self.y)
+
+class BinaryOp(Op2):
+ commutative = False
def generate(self, allocator):
try:
dstop = allocator.get_operand(self)
@@ -126,19 +134,41 @@
self.emit(mc, ecx, op2)
mc.MOV(dstop, ecx)
-class OpIntAdd(Op2):
+class OpIntAdd(BinaryOp):
opname = 'int_add'
emit = staticmethod(I386CodeBuilder.ADD)
commutative = True
-class OpIntSub(Op2):
+class OpIntSub(BinaryOp):
opname = 'int_sub'
emit = staticmethod(I386CodeBuilder.SUB)
class OpIntMul(Op2):
opname = 'int_mul'
- emit = staticmethod(I386CodeBuilder.IMUL)
- commutative = True
+ def generate(self, allocator):
+ try:
+ dstop = allocator.get_operand(self)
+ except KeyError:
+ return # simple operation whose result is not used anyway
+ op1 = allocator.get_operand(self.x)
+ op2 = allocator.get_operand(self.y)
+ mc = allocator.mc
+ if isinstance(dstop, REG):
+ tmpop = dstop
+ else:
+ tmpop = ecx
+ if tmpop == op1:
+ mc.IMUL(tmpop, op2)
+ elif isinstance(op2, IMM32):
+ mc.IMUL(tmpop, op1, op2)
+ elif isinstance(op1, IMM32):
+ mc.IMUL(tmpop, op2, op1)
+ else:
+ if tmpop != op2:
+ mc.MOV(tmpop, op2)
+ mc.IMUL(tmpop, op1)
+ if dstop != tmpop:
+ mc.MOV(dstop, tmpop)
class OpIntFloorDiv(Op2):
opname = 'int_floordiv'
@@ -187,20 +217,41 @@
mc.MOV(ecx, srcop)
mc.CMP(ecx, dstop)
+class OpIntLt(OpCompare2):
+ opname = 'int_lt'
+ cc_result = Conditions['L']
+
+class OpIntLe(OpCompare2):
+ opname = 'int_le'
+ cc_result = Conditions['LE']
+
+class OpIntEq(OpCompare2):
+ opname = 'int_eq'
+ cc_result = Conditions['E']
+
+class OpIntNe(OpCompare2):
+ opname = 'int_ne'
+ cc_result = Conditions['NE']
+
class OpIntGt(OpCompare2):
opname = 'int_gt'
cc_result = Conditions['G']
+class OpIntGe(OpCompare2):
+ opname = 'int_ge'
+ cc_result = Conditions['GE']
+
class JumpIf(Operation):
clobbers_cc = False
result_kind = RK_NO_RESULT
def __init__(self, gv_condition, targetbuilder, negate):
- assert 0 <= gv_condition.cc_result < INSN_JMP
self.gv_condition = gv_condition
self.targetbuilder = targetbuilder
self.negate = negate
def allocate(self, allocator):
allocator.using_cc(self.gv_condition)
+ for gv in self.targetbuilder.inputargs_gv:
+ allocator.using(gv)
def generate(self, allocator):
cc = self.gv_condition.cc_result
if self.negate:
@@ -307,13 +358,15 @@
del setup_opclasses
def setup_conditions():
- result = [None] * 16
+ result1 = [None] * 16
+ result2 = [None] * 16
for key, value in Conditions.items():
- result[value] = getattr(I386CodeBuilder, 'J'+key)
- return result
-EMIT_CONDITION = setup_conditions()
-INSN_JMP = len(EMIT_CONDITION)
-EMIT_CONDITION.append(I386CodeBuilder.JMP)
+ result1[value] = getattr(I386CodeBuilder, 'J'+key)
+ result2[value] = getattr(I386CodeBuilder, 'SET'+key)
+ return result1, result2
+EMIT_JCOND, EMIT_SETCOND = setup_conditions()
+INSN_JMP = len(EMIT_JCOND)
+EMIT_JCOND.append(I386CodeBuilder.JMP) # not really a conditional jump
del setup_conditions
def cond_negate(cond):
@@ -387,17 +440,21 @@
# common case: v is a compare operation whose result is precisely
# what we need to be in the CC
self.need_var_in_cc = None
+ self.creating(v)
def save_cc(self):
# we need a value to be in the CC, but we see a clobbering
# operation, so we copy the original CC-creating operation down
# past the clobbering operation
v = self.need_var_in_cc
+ if not we_are_translated():
+ assert v in self.operations[:self.operationindex]
self.operations.insert(self.operationindex, v)
self.need_var_in_cc = None
def using_cc(self, v):
- assert not v.is_const
+ assert isinstance(v, Operation)
+ assert 0 <= v.cc_result < INSN_JMP
if self.need_var_in_cc is not None:
self.save_cc()
self.need_var_in_cc = v
@@ -426,26 +483,32 @@
force_operand2loc = self.force_operand2loc
for i in range(len(force_vars)):
v = force_vars[i]
+ operand = force_operands[i]
try:
loc = self.var2loc[v]
except KeyError:
- pass
+ if at_start:
+ raise NotImplementedError
+ else:
+ self.add_final_move(v, operand)
else:
- operand = force_operands[i]
if loc in force_loc2operand or operand in force_operand2loc:
if at_start:
self.initial_moves.append((loc, operand))
else:
- v2 = OpSameAs(v)
- self.operations.append(v2)
- loc = self.nextloc
- self.nextloc += 1
- self.var2loc[v2] = loc
- force_loc2operand[loc] = operand
+ self.add_final_move(v, operand)
else:
force_loc2operand[loc] = operand
force_operand2loc[operand] = loc
+ def add_final_move(self, v, targetoperand):
+ v2 = OpSameAs(v)
+ self.operations.append(v2)
+ loc = self.nextloc
+ self.nextloc += 1
+ self.var2loc[v2] = loc
+ self.force_loc2operand[loc] = targetoperand
+
def allocate_registers(self):
# assign registers to locations that don't have one already
force_loc2operand = self.force_loc2operand
@@ -513,6 +576,23 @@
if self.operands[loc] != srcoperand:
self.mc.POP(self.operands[loc])
+ def generate_operations(self):
+ for v in self.operations:
+ v.generate(self)
+ cc = v.cc_result
+ if cc >= 0 and v in self.var2loc:
+ # force a comparison instruction's result into a
+ # regular location
+ dstop = self.get_operand(v)
+ mc = self.mc
+ insn = EMIT_SETCOND[cc]
+ insn(mc, cl)
+ try:
+ mc.MOVZX(dstop, cl)
+ except FailedToImplement:
+ mc.MOVZX(ecx, cl)
+ mc.MOV(dstop, ecx)
+
class Builder(GenBuilder):
coming_from = 0
@@ -538,8 +618,7 @@
mc = self.start_mc()
allocator.mc = mc
allocator.generate_initial_moves()
- for op in self.operations:
- op.generate(allocator)
+ allocator.generate_operations()
self.operations = None
self.inputargs_gv = [GenVar() for v in final_vars_gv]
self.inputoperands = [allocator.get_operand(v) for v in final_vars_gv]
@@ -564,7 +643,7 @@
def set_coming_from(self, mc, insncond=INSN_JMP):
self.coming_from_cond = insncond
self.coming_from = mc.tell()
- insnemit = EMIT_CONDITION[insncond]
+ insnemit = EMIT_JCOND[insncond]
insnemit(mc, rel32(0))
def start_mc(self):
@@ -575,27 +654,28 @@
targetaddr = mc.tell()
end = start + 6 # XXX hard-coded, enough for JMP and Jcond
oldmc = self.rgenop.InMemoryCodeBuilder(start, end)
- insn = EMIT_CONDITION[self.coming_from_cond]
+ insn = EMIT_JCOND[self.coming_from_cond]
insn(oldmc, rel32(targetaddr))
oldmc.done()
self.coming_from = 0
return mc
- def jump_if_false(self, gv_condition, args_for_jump_gv):
+ def _jump_if(self, gv_condition, args_for_jump_gv, negate):
newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None)
- if gv_condition.cc_result < 0:
+ # if the condition does not come from an obvious comparison operation,
+ # e.g. a getfield of a Bool or an input argument to the current block,
+ # then insert an OpIntIsTrue
+ if gv_condition.cc_result < 0 or gv_condition not in self.operations:
gv_condition = OpIntIsTrue(gv_condition)
self.operations.append(gv_condition)
- self.operations.append(JumpIf(gv_condition, newbuilder, negate=True))
+ self.operations.append(JumpIf(gv_condition, newbuilder, negate=negate))
return newbuilder
+ def jump_if_false(self, gv_condition, args_for_jump_gv):
+ return self._jump_if(gv_condition, args_for_jump_gv, True)
+
def jump_if_true(self, gv_condition, args_for_jump_gv):
- newbuilder = Builder(self.rgenop, list(args_for_jump_gv), None)
- if gv_condition.cc_result < 0:
- gv_condition = OpIntIsTrue(gv_condition)
- self.operations.append(gv_condition)
- self.operations.append(JumpIf(gv_condition, newbuilder, negate=False))
- return newbuilder
+ return self._jump_if(gv_condition, args_for_jump_gv, False)
def finish_and_goto(self, outputargs_gv, targetlbl):
operands = targetlbl.inputoperands
From ericvrp at codespeak.net Sat Jan 13 15:18:14 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 13 Jan 2007 15:18:14 +0100 (CET)
Subject: [pypy-svn] r36658 - pypy/dist/pypy/jit/codegen/test
Message-ID: <20070113141814.431DD10083@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 13 15:18:12 2007
New Revision: 36658
Modified:
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
Missing builder.end() calls cause the llvm backend to segfault because
actual compilation is done in the end() method!
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 15:18:12 2007
@@ -403,6 +403,7 @@
return_false_builder.start_writing()
return_false_builder.finish_and_return(sigtoken, rgenop.genconst(0))
+ builder.end()
return gv_f
def make_condition_result_cross_link(rgenop):
@@ -425,6 +426,7 @@
target2.start_writing()
target2.finish_and_return(sigtoken, rgenop.genconst(3))
+ builder.end()
return gv_f
class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
From cfbolz at codespeak.net Sat Jan 13 15:26:11 2007
From: cfbolz at codespeak.net (cfbolz at codespeak.net)
Date: Sat, 13 Jan 2007 15:26:11 +0100 (CET)
Subject: [pypy-svn] r36659 - pypy/dist/pypy/objspace/std/test
Message-ID: <20070113142611.B620D10083@code0.codespeak.net>
Author: cfbolz
Date: Sat Jan 13 15:26:11 2007
New Revision: 36659
Modified:
pypy/dist/pypy/objspace/std/test/test_shadowtracking.py
Log:
(cfbolz, pedronis): actually _use_ shadow tracking when testing it :-(.
Modified: pypy/dist/pypy/objspace/std/test/test_shadowtracking.py
==============================================================================
--- pypy/dist/pypy/objspace/std/test/test_shadowtracking.py (original)
+++ pypy/dist/pypy/objspace/std/test/test_shadowtracking.py Sat Jan 13 15:26:11 2007
@@ -76,6 +76,9 @@
assert w_inst.w__dict__.implementation.shadows_anything
class AppTestShadowTracking(object):
+ def setup_class(cls):
+ cls.space = gettestobjspace(**{"objspace.std.withshadowtracking": True})
+
def test_shadowtracking_does_not_blow_up(self):
class A(object):
def f(self):
From arigo at codespeak.net Sat Jan 13 15:43:53 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 15:43:53 +0100 (CET)
Subject: [pypy-svn] r36660 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113144353.1EF4A10082@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 15:43:51 2007
New Revision: 36660
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Support for pause_writing().
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 15:43:51 2007
@@ -488,7 +488,7 @@
loc = self.var2loc[v]
except KeyError:
if at_start:
- raise NotImplementedError
+ pass # input variable not used anyway
else:
self.add_final_move(v, operand)
else:
@@ -596,6 +596,7 @@
class Builder(GenBuilder):
coming_from = 0
+ operations = None
def __init__(self, rgenop, inputargs_gv, inputoperands):
self.rgenop = rgenop
@@ -603,12 +604,16 @@
self.inputoperands = inputoperands
def start_writing(self):
+ assert self.operations is None
self.operations = []
def generate_block_code(self, final_vars_gv, force_vars=[],
- force_operands=[]):
+ force_operands=[],
+ renaming=True):
allocator = RegAllocator()
allocator.set_final(final_vars_gv)
+ if not renaming:
+ final_vars_gv = allocator.var2loc.keys() # unique final vars
allocator.allocate_locations(self.operations)
allocator.force_var_operands(force_vars, force_operands,
at_start=False)
@@ -620,7 +625,11 @@
allocator.generate_initial_moves()
allocator.generate_operations()
self.operations = None
- self.inputargs_gv = [GenVar() for v in final_vars_gv]
+ if renaming:
+ self.inputargs_gv = [GenVar() for v in final_vars_gv]
+ else:
+ # just keep one copy of each Variable that is alive
+ self.inputargs_gv = final_vars_gv
self.inputoperands = [allocator.get_operand(v) for v in final_vars_gv]
return mc
@@ -697,6 +706,12 @@
# ----------------
self.rgenop.close_mc(mc)
+ def pause_writing(self, alive_gv):
+ mc = self.generate_block_code(alive_gv, renaming=False)
+ self.set_coming_from(mc)
+ self.rgenop.close_mc(mc)
+ return self
+
def end(self):
pass
From ericvrp at codespeak.net Sat Jan 13 16:00:47 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 13 Jan 2007 16:00:47 +0100 (CET)
Subject: [pypy-svn] r36661 - in pypy/dist/pypy/jit/codegen: llvm llvm/test
test
Message-ID: <20070113150047.49B6410063@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 13 16:00:45 2007
New Revision: 36661
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
Another missing builder.end(), more tests pass
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Sat Jan 13 16:00:45 2007
@@ -217,7 +217,8 @@
return '%s %s' % (self.type, self.operand2())
def operand2(self):
- s = str(llmemory.cast_adr_to_int(self.addr))
+ addr = self.addr
+ s = str(llmemory.cast_adr_to_int(addr))
if s == '0':
s = 'null'
return s
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_ts.py Sat Jan 13 16:00:45 2007
@@ -27,5 +27,3 @@
test_two_loops_merging = skip_too_minimal #segfault
test_green_char_at_merge = skip #segfault
test_residual_red_call_with_exc = skip
- else: #needs fixing for >= 2.0
- test_array_of_voids = skip
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py Sat Jan 13 16:00:45 2007
@@ -24,6 +24,4 @@
test_goto_compile = skip_too_minimal #segfault
test_fact_direct = skip_too_minimal #segfault
- test_fact_compile = skip #XXX Blocked block, introducted by this checkin (I don't understand)
- test_calling_pause_direct = skip #segfault, look into later...
- test_calling_pause_compile = skip # dito
+ test_fact_compile = skip #XXX Blocked block, (addr = self.addr) in AddrConst.operand2()
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 16:00:45 2007
@@ -355,6 +355,7 @@
builder.start_writing()
builder.finish_and_return(sigtoken, gv_x)
+ builder.end()
return gv_f
def get_func_calling_pause_runner(RGenOp):
From arigo at codespeak.net Sat Jan 13 16:16:00 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 16:16:00 +0100 (CET)
Subject: [pypy-svn] r36662 - pypy/dist/pypy/jit/codegen/test
Message-ID: <20070113151600.9849910083@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 16:15:59 2007
New Revision: 36662
Modified:
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
Add a test.
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 16:15:59 2007
@@ -750,3 +750,34 @@
res = fnptr(2)
assert res == 101010
+
+ def test_tight_loop(self):
+ # while 1:
+ # y = x - 7
+ # if y < 0: break
+ # x = y
+ # return x
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "tightloop")
+ args_gv = [gv_x]
+ loopstart = builder.enter_next_block([signed_kind], args_gv)
+ [gv_x] = args_gv
+
+ gv_y = builder.genop2("int_sub", gv_x, rgenop.genconst(7))
+ gv_cond = builder.genop2("int_lt", gv_y, rgenop.genconst(0))
+ end_builder = builder.jump_if_true(gv_cond, [gv_x])
+ builder.finish_and_goto([gv_y], loopstart)
+
+ end_builder.start_writing()
+ end_builder.finish_and_return(sigtoken, gv_x)
+ builder.end()
+ fnptr = self.cast(gv_callable, 1)
+
+ res = fnptr(5)
+ assert res == 5
+
+ res = fnptr(44)
+ assert res == 2
From arigo at codespeak.net Sat Jan 13 16:17:42 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 16:17:42 +0100 (CET)
Subject: [pypy-svn] r36663 - in pypy/branch/i386-regalloc/pypy/jit/codegen:
llvm llvm/test test
Message-ID: <20070113151742.D235A10083@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 16:17:41 2007
New Revision: 36663
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
svn merge -r36654:36662 http://codespeak.net/svn/pypy/dist/pypy/jit/codegen
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py Sat Jan 13 16:17:41 2007
@@ -217,7 +217,8 @@
return '%s %s' % (self.type, self.operand2())
def operand2(self):
- s = str(llmemory.cast_adr_to_int(self.addr))
+ addr = self.addr
+ s = str(llmemory.cast_adr_to_int(addr))
if s == '0':
s = 'null'
return s
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_genc_ts.py Sat Jan 13 16:17:41 2007
@@ -27,5 +27,3 @@
test_two_loops_merging = skip_too_minimal #segfault
test_green_char_at_merge = skip #segfault
test_residual_red_call_with_exc = skip
- else: #needs fixing for >= 2.0
- test_array_of_voids = skip
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py Sat Jan 13 16:17:41 2007
@@ -24,6 +24,4 @@
test_goto_compile = skip_too_minimal #segfault
test_fact_direct = skip_too_minimal #segfault
- test_fact_compile = skip #XXX Blocked block, introducted by this checkin (I don't understand)
- test_calling_pause_direct = skip #segfault, look into later...
- test_calling_pause_compile = skip # dito
+ test_fact_compile = skip #XXX Blocked block, (addr = self.addr) in AddrConst.operand2()
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 16:17:41 2007
@@ -412,6 +412,7 @@
builder.start_writing()
builder.finish_and_return(sigtoken, gv_x)
+ builder.end()
return gv_f
def get_func_calling_pause_runner(RGenOp):
@@ -460,6 +461,7 @@
return_false_builder.start_writing()
return_false_builder.finish_and_return(sigtoken, rgenop.genconst(0))
+ builder.end()
return gv_f
def make_condition_result_cross_link(rgenop):
@@ -482,6 +484,7 @@
target2.start_writing()
target2.finish_and_return(sigtoken, rgenop.genconst(3))
+ builder.end()
return gv_f
class AbstractRGenOpTests(test_boehm.AbstractGCTestClass):
@@ -818,3 +821,34 @@
res = fnptr(2)
assert res == 101010
+
+ def test_tight_loop(self):
+ # while 1:
+ # y = x - 7
+ # if y < 0: break
+ # x = y
+ # return x
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "tightloop")
+ args_gv = [gv_x]
+ loopstart = builder.enter_next_block([signed_kind], args_gv)
+ [gv_x] = args_gv
+
+ gv_y = builder.genop2("int_sub", gv_x, rgenop.genconst(7))
+ gv_cond = builder.genop2("int_lt", gv_y, rgenop.genconst(0))
+ end_builder = builder.jump_if_true(gv_cond, [gv_x])
+ builder.finish_and_goto([gv_y], loopstart)
+
+ end_builder.start_writing()
+ end_builder.finish_and_return(sigtoken, gv_x)
+ builder.end()
+ fnptr = self.cast(gv_callable, 1)
+
+ res = fnptr(5)
+ assert res == 5
+
+ res = fnptr(44)
+ assert res == 2
From hpk at codespeak.net Sat Jan 13 16:20:47 2007
From: hpk at codespeak.net (hpk at codespeak.net)
Date: Sat, 13 Jan 2007 16:20:47 +0100 (CET)
Subject: [pypy-svn] r36665 - in pypy/dist/pypy: doc doc/weekly tool/build
Message-ID: <20070113152047.B5B6B10083@code0.codespeak.net>
Author: hpk
Date: Sat Jan 13 16:20:46 2007
New Revision: 36665
Modified:
pypy/dist/pypy/doc/confrest.py
pypy/dist/pypy/doc/conftest.py
pypy/dist/pypy/doc/weekly/confrest.py
pypy/dist/pypy/tool/build/conftest.py
Log:
use py/doc instead of py/documentation
Modified: pypy/dist/pypy/doc/confrest.py
==============================================================================
--- pypy/dist/pypy/doc/confrest.py (original)
+++ pypy/dist/pypy/doc/confrest.py Sat Jan 13 16:20:46 2007
@@ -1,4 +1,4 @@
-from py.__.documentation.confrest import *
+from py.__.doc.confrest import *
class PyPyPage(Page):
def fill(self):
Modified: pypy/dist/pypy/doc/conftest.py
==============================================================================
--- pypy/dist/pypy/doc/conftest.py (original)
+++ pypy/dist/pypy/doc/conftest.py Sat Jan 13 16:20:46 2007
@@ -1,5 +1,5 @@
import py
-from py.__.documentation.conftest import Directory, DoctestText, ReSTChecker
+from py.__.doc.conftest import Directory, DoctestText, ReSTChecker
Option = py.test.Config.Option
option = py.test.Config.addoptions("pypy-doc options",
Modified: pypy/dist/pypy/doc/weekly/confrest.py
==============================================================================
--- pypy/dist/pypy/doc/weekly/confrest.py (original)
+++ pypy/dist/pypy/doc/weekly/confrest.py Sat Jan 13 16:20:46 2007
@@ -1,4 +1,4 @@
-from py.__.documentation.confrest import *
+from py.__.doc.confrest import *
class PyPyPage(Page):
def fill(self):
Modified: pypy/dist/pypy/tool/build/conftest.py
==============================================================================
--- pypy/dist/pypy/tool/build/conftest.py (original)
+++ pypy/dist/pypy/tool/build/conftest.py Sat Jan 13 16:20:46 2007
@@ -1,5 +1,5 @@
import py
-from py.__.documentation.conftest import Directory as Dir, DoctestText, \
+from py.__.doc.conftest import Directory as Dir, DoctestText, \
ReSTChecker
mypath = py.magic.autopath().dirpath()
From arigo at codespeak.net Sat Jan 13 16:27:37 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 16:27:37 +0100 (CET)
Subject: [pypy-svn] r36666 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113152737.F211C10087@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 16:27:36 2007
New Revision: 36666
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Fix jumps back to the same currently-open block.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 16:27:36 2007
@@ -689,7 +689,12 @@
def finish_and_goto(self, outputargs_gv, targetlbl):
operands = targetlbl.inputoperands
if operands is None:
- raise NotImplementedError
+ # this occurs when jumping back to the same currently-open block;
+ # close the block and re-open it
+ self.pause_writing(outputargs_gv)
+ self.start_writing()
+ operands = targetlbl.inputoperands
+ assert operands is not None
mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands)
mc.JMP(rel32(targetlbl.targetaddr))
self.rgenop.close_mc(mc)
From fijal at codespeak.net Sat Jan 13 16:31:46 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 16:31:46 +0100 (CET)
Subject: [pypy-svn] r36669 - in pypy/dist/pypy/rpython/ootypesystem: . test
Message-ID: <20070113153146.DDA3510087@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 16:31:45 2007
New Revision: 36669
Modified:
pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
pypy/dist/pypy/rpython/ootypesystem/extdesc.py
pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
Log:
(antonio, fijal) Create new interface for bltregistry, which kills several hacks
broken JS tests, will fix it probably today
Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Sat Jan 13 16:31:45 2007
@@ -10,18 +10,16 @@
from types import MethodType
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.ootypesystem.extdesc import MethodDesc, ArgDesc
+from pypy.annotation.signature import annotation
class CallableEntry(ExtRegistryEntry):
_type_ = MethodDesc
def compute_annotation(self):
- # because we have no good annotation
- # let's cheat a little bit for a while...
bookkeeper = getbookkeeper()
- # hack, hack, hack, hack, hack, hack, hack, hack, hack, hack, hack,
- values = ["v%d"%i for i in xrange(len(self.instance.args))]
- lb = eval("lambda %s: None" % ",".join(values))
- return annmodel.SomePBC([bookkeeper.getdesc(lb)])
+ args_s = [annotation(i._type) for i in self.instance.args]
+ s_result = annotation(self.instance.result._type)
+ return annmodel.SomeGenericCallable(args=args_s, result=s_result)
class BasicMetaExternal(type):
def _is_compatible(type2):
@@ -47,6 +45,7 @@
_methods = {}
def described(retval=None, args={}):
+ xxx # we'll fix that later
def decorator(func):
code = func.func_code
if not func.func_defaults:
@@ -57,7 +56,7 @@
assert(code.co_argcount < len(defs) + len(args), "Not enough information for describing method")
for arg in xrange(1, code.co_argcount - len(defs)):
- assert code.co_varnames[arg] in args, "Don't have example for arg %s" % code.co_varnames[arg]
+ assert code.co_varnames[arg] in args, "Don't have type for arg %s" % code.co_varnames[arg]
arg_pass = []
start_pos = code.co_argcount - len(defs)
@@ -84,10 +83,10 @@
self.value = value
def __call__(self, *args):
- for i in args:
- if isinstance(i, annmodel.SomePBC):
- bookkeeper = getbookkeeper()
- bookkeeper.pbc_call(i, bookkeeper.build_args("simple_call", (self.s_retval,)))
+ #for i in args:
+ # if isinstance(i, annmodel.SomePBC):
+ # bookkeeper = getbookkeeper()
+ # bookkeeper.pbc_call(i, bookkeeper.build_args("simple_call", (self.s_retval,)))
return self.s_retval
class ExternalType(ootype.OOType):
@@ -104,7 +103,7 @@
def update_fields(self, _fields):
for i, val in _fields.iteritems():
- self._fields[i] = getbookkeeper().annotation_from_example(val)
+ self._fields[i] = annotation(val)
def _is_compatible(type2):
return type(type2) is ExternalType
@@ -115,9 +114,10 @@
_signs = {}
self._fields = {}
for i, val in _methods.iteritems():
- retval = getbookkeeper().annotation_from_example(val.retval.example)
- values = [arg.example for arg in val.args]
- s_args = [getbookkeeper().annotation_from_example(j) for j in values]
+ #s_retval =
+ retval = annotation(val.retval._type)
+ values = [arg._type for arg in val.args]
+ s_args = [annotation(j) for j in values]
_signs[i] = MethodDesc(tuple(s_args), retval)
next = annmodel.SomeBuiltin(Analyzer(i, val, retval, s_args), s_self = annmodel.SomeExternalBuiltin(self), methodname = i)
next.const = True
@@ -166,15 +166,12 @@
def compute_annotation(self):
return annmodel.SomeExternalBuiltin(self.bookkeeper.getexternaldesc\
(self.instance.__class__))
- #return annmodel.SomeExternalBuiltin(ExternalType.get(self.instance.__class__))
def get_field_annotation(self, ext_obj, attr):
return ext_obj.get_field(attr)
def get_arg_annotation(self, ext_obj, attr):
- field = ext_obj._class_._fields[attr]
- assert isinstance(field, MethodDesc)
- return [getbookkeeper().annotation_from_example(arg.example) for arg in field.args]
+ return ext_obj._class_._fields[attr].args_s
def set_field_annotation(self, ext_obj, attr, s_val):
ext_obj.set_field(attr, s_val)
@@ -189,6 +186,3 @@
value = hop.r_result.lowleveltype
return hop.genop('new', [Constant(value, concretetype=ootype.Void)], \
resulttype = value)
-
-#def rebuild_basic_external():
-# ExternalType.class_dict = {}
Modified: pypy/dist/pypy/rpython/ootypesystem/extdesc.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/extdesc.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/extdesc.py Sat Jan 13 16:31:45 2007
@@ -6,12 +6,12 @@
""" Description of argument, given as name + example value
(used to deduce type)
"""
- def __init__(self, name, ex_value):
+ def __init__(self, name, _type):
self.name = name
- self.example = ex_value
+ self._type = _type
def __repr__(self):
- return "" % (self.name, self.example)
+ return "" % (self.name, self._type)
class MethodDesc(object):
""" Description of method to be external,
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Sat Jan 13 16:31:45 2007
@@ -2,6 +2,7 @@
""" Builtin annotation test
"""
+import py
from pypy.annotation import model as annmodel
from pypy.objspace.flow import FlowObjSpace
from pypy.annotation.annrpython import RPythonAnnotator
@@ -9,6 +10,7 @@
from pypy.rpython.ootypesystem.bltregistry import BasicExternal, ExternalType, MethodDesc
from pypy.rpython.ootypesystem.ootype import Signed, _static_meth, StaticMethod, Void
from pypy.rpython.test.test_llinterp import interpret
+from pypy.annotation.signature import annotation
class C(BasicExternal):
pass
@@ -24,7 +26,7 @@
class A(BasicExternal):
_fields = {
- 'b' : 3,
+ 'b' : int,
}
def test_bltn_attrs():
@@ -51,11 +53,11 @@
class B(BasicExternal):
_fields = {
- 'a' : 32,
+ 'a' : int,
}
_methods = {
- 'm' : MethodDesc([1],2),
+ 'm' : MethodDesc([int], int),
}
def test_bltn_method():
@@ -79,14 +81,14 @@
class CB(BasicExternal):
_fields = {
- 'm': MethodDesc([], 3), # XXX maybe
+ 'm': annmodel.SomeGenericCallable(
+ args=[], result=annmodel.SomeInteger()),
}
def some_int():
return 3
def test_flowin():
- import py; py.test.skip("Indirect call is missing")
def set_callback():
a = CB()
a.m = some_int
@@ -98,7 +100,10 @@
class CC(BasicExternal):
_methods = {
- 'some_method' : MethodDesc(['some_callback', MethodDesc([('some_int', 3)], 3.0)], 3)
+ 'some_method' : MethodDesc(
+ [annmodel.SomeGenericCallable(args=[
+ annmodel.SomeInteger()], result=annmodel.SomeFloat())],
+ int)
}
def test_callback_flowin():
@@ -115,7 +120,9 @@
class CD(BasicExternal):
_fields = {
- 'callback_field' : MethodDesc([('some_int', 3)], 3.0)
+ 'callback_field' :
+ annmodel.SomeGenericCallable([annmodel.SomeInteger()],
+ annmodel.SomeFloat())
}
def test_callback_field():
@@ -129,4 +136,4 @@
a = RPythonAnnotator()
s = a.build_types(callback_field, [])
- assert isinstance(s, annmodel.SomePBC)
+ assert isinstance(s, annmodel.SomeGenericCallable)
From fijal at codespeak.net Sat Jan 13 17:08:20 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 17:08:20 +0100 (CET)
Subject: [pypy-svn] r36672 - pypy/dist/pypy/translator/js/test
Message-ID: <20070113160820.031DB10083@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 17:08:18 2007
New Revision: 36672
Modified:
pypy/dist/pypy/translator/js/test/test_basicexternal.py
Log:
Adopt a test to new API
Modified: pypy/dist/pypy/translator/js/test/test_basicexternal.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_basicexternal.py (original)
+++ pypy/dist/pypy/translator/js/test/test_basicexternal.py Sat Jan 13 17:08:18 2007
@@ -9,7 +9,7 @@
from pypy.translator.js.tester import schedule_callbacks
class A(BasicExternal):
- @described(retval=3)
+ @described(retval=int)
def some_code(self, var="aa"):
pass
@@ -49,7 +49,7 @@
## assert fun() == 3
class EE(BasicExternal):
- @described(retval=3)
+ @described(retval=int)
def bb(self):
pass
@@ -64,7 +64,7 @@
assert check_source_contains(fun, "EE = ee")
class C(BasicExternal):
- @described(retval=3)
+ @described(retval=int)
def f(self):
pass
@@ -84,11 +84,11 @@
class D(BasicExternal):
_fields = {
- 'a': {"aa":"aa"},
- 'b': ["aa"],
+ 'a': {str:str},
+ 'b': [str],
}
-D._fields['c'] = [D(),D()]
+D._fields['c'] = [D]
d = D()
d._render_name = 'd'
@@ -114,7 +114,7 @@
def test_method_call():
class Meth(BasicExternal):
- @described(retval=3)
+ @described(retval=int)
def meth(self):
return 8
From fijal at codespeak.net Sat Jan 13 17:08:50 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 17:08:50 +0100 (CET)
Subject: [pypy-svn] r36673 - pypy/dist/pypy/rpython/ootypesystem
Message-ID: <20070113160850.BAC1E10088@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 17:08:49 2007
New Revision: 36673
Modified:
pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
Log:
Slight fix to avoid usage of instance
Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Sat Jan 13 17:08:49 2007
@@ -37,6 +37,18 @@
_is_compatible = staticmethod(_is_compatible)
+def typeof(val):
+ """ Small wrapper, which tries to resemble example -> python type
+ which can go to annotation path
+ """
+ if isinstance(val, list):
+ return [typeof(val[0])]
+ if isinstance(val, dict):
+ return {typeof(val.keys()[0]):typeof(val.values()[0])}
+ if isinstance(val, tuple):
+ return tuple([typeof(i) for i in val])
+ return type(val)
+
class BasicExternal(object):
__metaclass__ = BasicMetaExternal
__self__ = None
@@ -45,7 +57,6 @@
_methods = {}
def described(retval=None, args={}):
- xxx # we'll fix that later
def decorator(func):
code = func.func_code
if not func.func_defaults:
@@ -65,7 +76,7 @@
if varname in args:
arg_pass.append((varname, args[varname]))
else:
- arg_pass.append((varname, defs[arg - start_pos]))
+ arg_pass.append((varname, typeof(defs[arg - start_pos])))
func._method = (func.__name__, MethodDesc(arg_pass, retval))
return func
return decorator
@@ -165,7 +176,7 @@
def compute_annotation(self):
return annmodel.SomeExternalBuiltin(self.bookkeeper.getexternaldesc\
- (self.instance.__class__))
+ (self.type))
def get_field_annotation(self, ext_obj, attr):
return ext_obj.get_field(attr)
From fijal at codespeak.net Sat Jan 13 17:09:06 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 17:09:06 +0100 (CET)
Subject: [pypy-svn] r36674 - pypy/dist/pypy/annotation
Message-ID: <20070113160906.25E061008A@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 17:09:04 2007
New Revision: 36674
Modified:
pypy/dist/pypy/annotation/signature.py
Log:
try to get bookkeeper if possible
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Sat Jan 13 17:09:04 2007
@@ -9,6 +9,9 @@
def annotation(t, bookkeeper=None):
from pypy.rpython.lltypesystem import lltype
+ from pypy.annotation.bookkeeper import getbookkeeper
+ if bookkeeper is None:
+ bookkeeper = getbookkeeper()
if isinstance(t, SomeObject):
return t
From arigo at codespeak.net Sat Jan 13 17:22:03 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 17:22:03 +0100 (CET)
Subject: [pypy-svn] r36676 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113162203.C16E91008A@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 17:22:02 2007
New Revision: 36676
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Calls.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 17:22:02 2007
@@ -1,3 +1,4 @@
+import sys
from pypy.rlib.objectmodel import specialize, we_are_translated
from pypy.rpython.lltypesystem import lltype, llmemory
from pypy.jit.codegen.model import AbstractRGenOp, GenLabel, GenBuilder
@@ -9,6 +10,12 @@
WORD = 4 # bytes
+if sys.platform == 'darwin':
+ CALL_ALIGN = 4
+else:
+ CALL_ALIGN = 1
+
+PROLOGUE_FIXED_WORDS = 5
RK_NO_RESULT = 0
RK_WORD = 1
@@ -280,6 +287,53 @@
targetaddr = 0
inputoperands = None
+class OpCall(Operation):
+ def __init__(self, sigtoken, gv_fnptr, args_gv):
+ self.sigtoken = sigtoken
+ self.gv_fnptr = gv_fnptr
+ self.args_gv = args_gv
+ def allocate(self, allocator):
+ # XXX try to use eax for the result
+ allocator.using(self.gv_fnptr)
+ for v in self.args_gv:
+ allocator.using(v)
+ def generate(self, allocator):
+ try:
+ dstop = allocator.get_operand(self)
+ except KeyError:
+ dstop = None
+ mc = allocator.mc
+ stack_align_words = PROLOGUE_FIXED_WORDS
+ if dstop != eax:
+ mc.PUSH(eax)
+ if CALL_ALIGN > 1: stack_align_words += 1
+ if dstop != edx:
+ mc.PUSH(edx)
+ if CALL_ALIGN > 1: stack_align_words += 1
+ args_gv = self.args_gv
+ num_placeholders = 0
+ if CALL_ALIGN > 1:
+ stack_align_words += len(args_gv)
+ stack_align_words &= CALL_ALIGN-1
+ if stack_align_words > 0:
+ num_placeholders = CALL_ALIGN - stack_align_words
+ mc.SUB(esp, imm(WORD * num_placeholders))
+ for i in range(len(args_gv)-1, -1, -1):
+ srcop = allocator.get_operand(args_gv[i])
+ mc.PUSH(srcop)
+ fnop = allocator.get_operand(self.gv_fnptr)
+ if isinstance(fnop, IMM32):
+ mc.CALL(rel32(fnop.value))
+ else:
+ mc.CALL(fnop)
+ mc.ADD(esp, imm(WORD * (len(args_gv) + num_placeholders)))
+ if dstop != edx:
+ mc.POP(edx)
+ if dstop != eax:
+ if dstop is not None:
+ mc.MOV(dstop, eax)
+ mc.POP(eax)
+
# ____________________________________________________________
class IntConst(GenConst):
@@ -394,7 +448,8 @@
class RegAllocator(object):
- AVAILABLE_REGS = [eax, edx, ebx, esi, edi] # XXX ecx reserved for stuff
+ #AVAILABLE_REGS = [eax, edx, ebx, esi, edi] # XXX ecx reserved for stuff
+ AVAILABLE_REGS = [eax]
# 'gv' -- GenVars, used as arguments and results of operations
#
@@ -566,6 +621,8 @@
if last_n < n:
last_n = n
if last_n >= 0:
+ if CALL_ALIGN > 1:
+ last_n = (last_n & ~(CALL_ALIGN-1)) + (CALL_ALIGN-1)
self.mc.LEA(esp, stack_op(last_n))
# XXX naive algo for now
for loc, srcoperand in initial_moves:
@@ -736,6 +793,11 @@
self.operations.append(op)
return op
+ def genop_call(self, sigtoken, gv_fnptr, args_gv):
+ op = OpCall(sigtoken, gv_fnptr, list(args_gv))
+ self.operations.append(op)
+ return op
+
class RI386GenOp(AbstractRGenOp):
from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
@@ -777,6 +839,7 @@
mc.PUSH(ebx)
mc.PUSH(esi)
mc.PUSH(edi)
+ # ^^^ pushed 5 words including the retval ( == PROLOGUE_FIXED_WORDS)
self.close_mc(mc)
# NB. a bit of a hack: the first generated block of the function
# will immediately follow, by construction
From arigo at codespeak.net Sat Jan 13 17:43:31 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 17:43:31 +0100 (CET)
Subject: [pypy-svn] r36677 - pypy/dist/pypy/doc
Message-ID: <20070113164331.BC88E10088@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 17:43:26 2007
New Revision: 36677
Modified:
pypy/dist/pypy/doc/standalone-howto.txt
Log:
Fix the link (py.test failed on the previous anchor, although it's really a conftest bug).
Add a note pointing to target files.
Modified: pypy/dist/pypy/doc/standalone-howto.txt
==============================================================================
--- pypy/dist/pypy/doc/standalone-howto.txt (original)
+++ pypy/dist/pypy/doc/standalone-howto.txt Sat Jan 13 17:43:26 2007
@@ -2,7 +2,16 @@
HOWTO: compile RPython code into a standalone executable
========================================================
-First, see this Disclaimer_ in the FAQ.
+(NOTE: you should first read the `FAQ entries`_ about Using the PyPy
+translation tool chain. This document is a quick introduction to the
+interactive way to compile your own RPython code. Keep in mind though
+that if you write a larger RPython program, the best and most flexible
+way to compile it is not as described below, but by writing a target
+file as described in the `FAQ entries`_.)
+
+========================================
+
+First, see the note above.
Next, understand the restrictions on RPython_ code.
Pay close attention to the description of tuples and
dicts.
@@ -113,7 +122,7 @@
equivalents.
-.. _`Disclaimer`: faq.html#why-isn-t-there-a-simpler-way-of-doing-that
+.. _`FAQ Entries`: faq.html#using-the-pypy-translation-tool-chain
.. _`RPython`: coding-guide.html#restricted-python
.. _`Annotator`: dynamic-language-translation.html#annotator
.. _`RTyper`: dynamic-language-translation.html#rtyper
From arigo at codespeak.net Sat Jan 13 17:45:39 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 17:45:39 +0100 (CET)
Subject: [pypy-svn] r36678 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113164539.62BD310088@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 17:45:38 2007
New Revision: 36678
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
- successfully tested on an Intel Mac.
- give back all registers to the allocator (this was accidentally
checked in).
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 17:45:38 2007
@@ -448,8 +448,7 @@
class RegAllocator(object):
- #AVAILABLE_REGS = [eax, edx, ebx, esi, edi] # XXX ecx reserved for stuff
- AVAILABLE_REGS = [eax]
+ AVAILABLE_REGS = [eax, edx, ebx, esi, edi] # XXX ecx reserved for stuff
# 'gv' -- GenVars, used as arguments and results of operations
#
From mwh at codespeak.net Sat Jan 13 17:59:27 2007
From: mwh at codespeak.net (mwh at codespeak.net)
Date: Sat, 13 Jan 2007 17:59:27 +0100 (CET)
Subject: [pypy-svn] r36679 - in pypy/dist/pypy/translator/benchmark: . test
Message-ID: <20070113165927.23EA510088@code0.codespeak.net>
Author: mwh
Date: Sat Jan 13 17:59:18 2007
New Revision: 36679
Modified:
pypy/dist/pypy/translator/benchmark/bench-custom.py
pypy/dist/pypy/translator/benchmark/benchmarks.py
pypy/dist/pypy/translator/benchmark/result.py
pypy/dist/pypy/translator/benchmark/test/test_result.py
Log:
more benchmarking stuff. some horrible, horrible code in places, but it mostly
seems to work. bench-custom.py is much smaller now, have to be happy about that
Modified: pypy/dist/pypy/translator/benchmark/bench-custom.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/bench-custom.py (original)
+++ pypy/dist/pypy/translator/benchmark/bench-custom.py Sat Jan 13 17:59:18 2007
@@ -1,65 +1,67 @@
# benchmarks on a unix machine.
import autopath
-from pypy.translator.benchmark.result import BenchmarkResult
+from pypy.translator.benchmark.result import BenchmarkResultSet
from pypy.translator.benchmark.benchmarks import BENCHMARKS
-import os, sys, time, pickle, re
+import os, sys, time, pickle, re, py
def get_executables(args): #sorted by revision number (highest first)
- return sorted(args, key=os.path.getmtime)
+ exes = sorted(args, key=os.path.getmtime)
+ r = []
+ for exe in exes:
+ if '/' not in exe:
+ r.append('./' + exe)
+ else:
+ r.append(exe)
+ return r
def main(options, args):
- benchmark_result = BenchmarkResult('bench-custom.benchmark_result')
+ if os.path.exists(options.picklefile):
+ benchmark_result = pickle.load(open(options.picklefile, 'rb'))
+ else:
+ benchmark_result = BenchmarkResultSet()
- benchmarks = [b for b in BENCHMARKS if b[0] in options.benchmarks]
+ benchmarks = [b for b in BENCHMARKS if b.name in options.benchmarks]
exes = get_executables(args)
- pythons = 'python2.4 python2.3'.split()
- width = max(map(len, exes+pythons+['executable'])) + 3
+ pythons = 'python2.5 python2.4 python2.3'.split()
+ full_pythons = []
+ for python in pythons:
+ full_python = py.path.local.sysfind(python)
+ if full_python:
+ full_pythons.append(str(full_python))
- print 'date size codesize %-*s'%(width, 'executable'),
- for name, run, ascgood, units in benchmarks:
- print ' %-*s'%(6+len(units)+2+8+2-4, name),
- print
sys.stdout.flush()
refs = {}
- for exe in pythons+exes:
- exe_ = exe
- if exe in pythons:
- size = codesize = '-'
- ctime = time.ctime()
- else:
- size = os.path.getsize(exe)
- codesize = os.popen('size "%s" | tail -n1 | cut -f1'%(exe,)).read().strip()
- ctime = time.ctime(os.path.getmtime(exe))
- if '/' not in exe:
- exe_ = './' + exe
- print '%-26s %8s %8s %-*s'%(ctime, size, codesize, width, exe),
- sys.stdout.flush()
- for name, run, ascgood, units in benchmarks:
- n = exe + '_' + name
- if not benchmark_result.is_stable(n):
- benchmark_result.update(n, run(exe_), ascgood)
- res = benchmark_result.get_best_result(n)
- if name not in refs:
- refs[name] = res
- factor = res/refs[name]
- if ascgood:
- factor = 1/factor
- print "%6d%s (%6.1fx)"%(res, units, factor),
- sys.stdout.flush()
- print
+ exes = full_pythons+exes
- sys.stdout.flush()
+ for i in range(int(options.runcount)):
+ for exe in full_pythons+exes:
+ for b in benchmarks:
+ benchmark_result.result(exe).run_benchmark(b, verbose=True)
+
+ stats = ['stat:st_mtime', 'exe_name', 'bench:richards', 'pypy_rev', 'bench:pystone']
+ for row in benchmark_result.txt_summary(stats,
+ relto=full_pythons[0],
+ filteron=lambda r: r.exe_name in exes):
+ print row
if __name__ == '__main__':
from optparse import OptionParser
parser = OptionParser()
parser.add_option(
'--benchmarks', dest='benchmarks',
- default=','.join([b[0] for b in BENCHMARKS])
+ default=','.join([b.name for b in BENCHMARKS])
+ )
+ parser.add_option(
+ '--pickle', dest='picklefile',
+ default='bench-custom.benchmark_result'
+ )
+ parser.add_option(
+ '--runcount', dest='runcount',
+ default='1',
)
options, args = parser.parse_args(sys.argv[1:])
main(options, args)
Modified: pypy/dist/pypy/translator/benchmark/benchmarks.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/benchmarks.py (original)
+++ pypy/dist/pypy/translator/benchmark/benchmarks.py Sat Jan 13 17:59:18 2007
@@ -18,6 +18,13 @@
return 99999.0
return float(line.split()[len(pattern.split())])
+class Benchmark(object):
+ def __init__(self, name, runner, asc_good, units):
+ self.name = name
+ self.run = runner
+ self.asc_good = asc_good
+ self.units = units
+
def run_cmd(cmd):
#print "running", cmd
pipe = os.popen(cmd + ' 2>&1')
@@ -50,7 +57,11 @@
return 99999.0
return 1000*(float(m.group('mins'))*60 + float(m.group('secs')))
-BENCHMARKS = [('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'),
- ('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''),
- ('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'),
+BENCHMARKS = [Benchmark('richards', run_richards, RICHARDS_ASCENDING_GOOD, 'ms'),
+ Benchmark('pystone', run_pystone, PYSTONE_ASCENDING_GOOD, ''),
+ Benchmark('translate', run_translate, RICHARDS_ASCENDING_GOOD, 'ms'),
]
+
+BENCHMARKS_BY_NAME = {}
+for _b in BENCHMARKS:
+ BENCHMARKS_BY_NAME[_b.name] = _b
Modified: pypy/dist/pypy/translator/benchmark/result.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/result.py (original)
+++ pypy/dist/pypy/translator/benchmark/result.py Sat Jan 13 17:59:18 2007
@@ -1,21 +1,140 @@
-import os, pickle
+import os, pickle, sys, time, re
+
+stat2title = {
+ 'stat:st_mtime': "date",
+ 'exe_name': "executable",
+ 'bench:richards': "richards",
+ 'bench:pystone': "pystone",
+}
+
+class BenchmarkResultSet(object):
+ def __init__(self, max_results=10):
+ self.benchmarks = {}
+ self.max_results = max_results
+
+ def result(self, exe):
+ if exe in self.benchmarks:
+ return self.benchmarks[exe]
+ else:
+ r = self.benchmarks[exe] = BenchmarkResult(exe, self.max_results)
+ return r
+
+ def txt_summary(self, stats, **kw):
+ sortkey = kw.get('sortby', 'stat:st_mtime')
+ lst = self.benchmarks.values()
+ lst.sort(key=lambda x:x.getstat(sortkey, None), reverse=kw.get('reverse', False))
+ if 'filteron' in kw:
+ filteron = kw['filteron']
+ lst = [r for r in lst if filteron(r)]
+ relto = kw.get('relto', None)
+ table = [[(stat2title.get(s,s),0) for s in stats]]
+ for r in lst:
+ row = []
+ for stat in stats:
+ if stat.startswith('bench:'):
+ benchname = stat[6:]
+ if r.getstat(stat, None) is None:
+ row.append(('XXX',-1))
+ elif relto:
+ factor = self.result(relto).getstat(stat)/r.getstat(stat)
+ if not r.asc_goods[benchname]:
+ factor = 1/factor
+ s, f = r.fmtstat(stat)
+ row.append((s + ' (%6.2fx)'%factor, f))
+ else:
+ row.append(r.fmtstat(stat))
+ else:
+ row.append(r.fmtstat(stat))
+ table.append(row)
+ widths = [0 for thing in stats]
+ for row in table:
+ for i, cell in enumerate(row):
+ widths[i] = max(len(cell[0]), widths[i])
+ concretetable = []
+ concreterow = []
+ for w, cell in zip(widths, table[0]):
+ concreterow.append(cell[0].center(w))
+ concretetable.append(' '.join(concreterow))
+ for row in table[1:]:
+ concreterow = []
+ for w, cell in zip(widths, row):
+ concreterow.append("%*s"%(cell[1]*w, cell[0]))
+ concretetable.append(' '.join(concreterow))
+ return concretetable
class BenchmarkResult(object):
- def __init__(self, filename, max_results=10):
- self.filename = filename
+ def __init__(self, exe, max_results=10):
self.max_results = max_results
- if os.path.exists(filename):
- f = open(filename, 'r')
- self.n_results = pickle.load(f)
- self.best_result = pickle.load(f)
- f.close()
- # any exception while loading the file is best reported
- # as a crash, instead of as a silent loss of all the
- # data :-/
+ self.exe_stat = os.stat(exe)
+ self.exe_name = exe
+ self.codesize = os.popen('size "%s" | tail -n1 | cut -f1'%(exe,)).read().strip()
+ try:
+ self.pypy_rev = int(os.popen(
+ exe + ' -c "import sys; print sys.pypy_version_info[-1]" 2>/dev/null').read().strip())
+ except ValueError:
+ self.pypy_rev = -1
+ self.best_benchmarks = {}
+ self.benchmarks = {}
+ self.asc_goods = {}
+ self.run_counts = {}
+
+ def run_benchmark(self, benchmark, verbose=False):
+ self.asc_goods[benchmark.name] = benchmark.asc_good
+ if self.run_counts.get(benchmark.name, 0) > self.max_results:
+ return
+ if verbose:
+ print 'running', benchmark.name, 'for', self.exe_name
+ new_result = benchmark.run(self.exe_name)
+ self.benchmarks.setdefault(benchmark.name, []).append(new_result)
+ if benchmark.name in self.best_benchmarks:
+ old_result = self.best_benchmarks[benchmark.name]
+ if benchmark.asc_good:
+ new_result = max(new_result, old_result)
+ else:
+ new_result = min(new_result, old_result)
+ self.best_benchmarks[benchmark.name] = new_result
+ self.run_counts[benchmark.name] = self.run_counts.get(benchmark.name, 0) + 1
+
+ def getstat(self, *args):
+ # oh for supplied-p!
+ return_default = False
+ if len(args) == 1:
+ stat, = args
+ else:
+ stat, default = args
+ return_default = True
+ if hasattr(self, stat):
+ return getattr(self, stat)
+ statkind, statdetail = stat.split(':')
+ if statkind == 'stat':
+ return getattr(self.exe_stat, statdetail)
+ elif statkind == 'bench':
+ if return_default:
+ return self.best_benchmarks.get(statdetail, default)
+ else:
+ return self.best_benchmarks[statdetail]
+ else:
+ 1/0
+
+ def fmtstat(self, *args):
+ stat = args[0]
+ statvalue = self.getstat(*args)
+ if stat == 'stat:st_mtime':
+ return time.ctime(statvalue), -1
+ elif stat == 'exe_name':
+ return os.path.basename(statvalue), -1
+ elif stat == 'bench:richards':
+ return "%8.2f%s"%(statvalue, 'ms'), 1
+ elif stat == 'bench:pystone':
+ return "%8.2f"%(statvalue,), 1
+ elif stat == 'pypy_rev':
+ return str(statvalue), 1
else:
- self.n_results = {}
- self.best_result = {}
+ return str(statvalue), -1
+
+ def summary(self, stats):
+ return [self.getstat(stat) for stat in stats]
def is_stable(self, name):
try:
@@ -23,22 +142,20 @@
except:
return False
- def update(self, name, result, ascending_good):
- try:
- if ascending_good:
- self.best_result[name] = max(self.best_result[name], result)
- else:
- self.best_result[name] = min(self.best_result[name], result)
- except KeyError:
- self.n_results[name] = 0
- self.best_result[name] = result
- self.n_results[name] += 1
-
- f = open(self.filename, 'w')
- pickle.dump(self.n_results , f)
- pickle.dump(self.best_result, f)
- f.close()
-
- def get_best_result(self, name):
- return self.best_result[name]
-
+if __name__ == '__main__':
+ import autopath
+ from pypy.translator.benchmark import benchmarks, result
+ import cPickle
+ if os.path.exists('foo.pickle'):
+ s = cPickle.load(open('foo.pickle', 'rb'))
+ else:
+ s = result.BenchmarkResultSet(4)
+ for exe in sys.argv[1:]:
+ r = s.result(exe)
+ r.run_benchmark(benchmarks.BENCHMARKS_BY_NAME['richards'])
+ r.run_benchmark(benchmarks.BENCHMARKS_BY_NAME['pystone'])
+ cPickle.dump(s, open('foo.pickle', 'wb'))
+ stats = ['stat:st_mtime', 'exe_name', 'bench:richards', 'bench:pystone']
+
+ for row in s.txt_summary(stats, sortby="exe_name", reverse=True, relto="/usr/local/bin/python2.4"):
+ print row
Modified: pypy/dist/pypy/translator/benchmark/test/test_result.py
==============================================================================
--- pypy/dist/pypy/translator/benchmark/test/test_result.py (original)
+++ pypy/dist/pypy/translator/benchmark/test/test_result.py Sat Jan 13 17:59:18 2007
@@ -1,11 +1,13 @@
import py
from pypy.translator.benchmark import result
+py.test.skip("not doing TDD for this :/")
+
temp = py.test.ensuretemp("report")
def test_simple():
fname = temp.join("simple")
- b = result.BenchmarkResult(str(fname), 3)
+ b = result.BenchmarkResult()
b.update('foo', 1, True)
assert b.get_best_result('foo') == 1
From fijal at codespeak.net Sat Jan 13 18:00:41 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 18:00:41 +0100 (CET)
Subject: [pypy-svn] r36680 - pypy/dist/pypy/annotation
Message-ID: <20070113170041.4DF2110089@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 18:00:35 2007
New Revision: 36680
Modified:
pypy/dist/pypy/annotation/signature.py
Log:
Add a None dispatching
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Sat Jan 13 18:00:35 2007
@@ -37,6 +37,8 @@
assert len(t) == 1, "We do not support type joining in dict"
return SomeDict(DictDef(None, annotation(t.keys()[0]),
annotation(t.values()[0])))
+ elif type(t) is types.NoneType:
+ return s_None
assert isinstance(t, (type, types.ClassType))
if t is bool:
return SomeBool()
From fijal at codespeak.net Sat Jan 13 18:14:12 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 18:14:12 +0100 (CET)
Subject: [pypy-svn] r36681 - in pypy/dist/pypy/translator/js/modules: . test
Message-ID: <20070113171412.B5D0B10074@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 18:14:07 2007
New Revision: 36681
Modified:
pypy/dist/pypy/translator/js/modules/dom.py
pypy/dist/pypy/translator/js/modules/test/test_dom.py
Log:
Wack test_dom and dom until it passes
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Sat Jan 13 18:14:07 2007
@@ -24,6 +24,9 @@
from pypy.translator.stackless.test.test_transform import one
from xml.dom import minidom
+from pypy.annotation.signature import annotation
+from pypy.annotation import model as annmodel
+
# EventTarget is the base class for Nodes and Window
class EventTarget(BasicExternal):
def addEventListener(self, type, listener, useCapture):
@@ -311,377 +314,382 @@
# rtyper stuff
+def _callable(args, result=None):
+ return annmodel.SomeGenericCallable([annotation(i) for i in args],
+ annotation(result))
+
EventTarget._fields = {
- 'onabort' : MethodDesc([Event()]),
- 'onblur' : MethodDesc([Event()]),
- 'onchange' : MethodDesc([Event()]),
- 'onclick' : MethodDesc([MouseEvent()]),
- 'onclose' : MethodDesc([MouseEvent()]),
- 'ondblclick' : MethodDesc([MouseEvent()]),
- 'ondragdrop' : MethodDesc([MouseEvent()]),
- 'onerror' : MethodDesc([MouseEvent()]),
- 'onfocus' : MethodDesc([Event()]),
- 'onkeydown' : MethodDesc([KeyEvent()]),
- 'onkeypress' : MethodDesc([KeyEvent()]),
- 'onkeyup' : MethodDesc([KeyEvent()]),
- 'onload' : MethodDesc([KeyEvent()]),
- 'onmousedown' : MethodDesc([MouseEvent()]),
- 'onmousemove' : MethodDesc([MouseEvent()]),
- 'onmouseup' : MethodDesc([MouseEvent()]),
- 'onmouseover' : MethodDesc([MouseEvent()]),
- 'onmouseup' : MethodDesc([MouseEvent()]),
- 'onresize' : MethodDesc([Event()]),
- 'onscroll' : MethodDesc([MouseEvent()]),
- 'onselect' : MethodDesc([MouseEvent()]),
- 'onsubmit' : MethodDesc([MouseEvent()]),
- 'onunload' : MethodDesc([Event()]),
+ 'onabort' : _callable([Event]),
+ 'onblur' : _callable([Event]),
+ 'onchange' : _callable([Event]),
+ 'onclick' : _callable([MouseEvent]),
+ 'onclose' : _callable([MouseEvent]),
+ 'ondblclick' : _callable([MouseEvent]),
+ 'ondragdrop' : _callable([MouseEvent]),
+ 'onerror' : _callable([MouseEvent]),
+ 'onfocus' : _callable([Event]),
+ 'onkeydown' : _callable([KeyEvent]),
+ 'onkeypress' : _callable([KeyEvent]),
+ 'onkeyup' : _callable([KeyEvent]),
+ 'onload' : _callable([KeyEvent]),
+ 'onmousedown' : _callable([MouseEvent]),
+ 'onmousemove' : _callable([MouseEvent]),
+ 'onmouseup' : _callable([MouseEvent]),
+ 'onmouseover' : _callable([MouseEvent]),
+ 'onmouseup' : _callable([MouseEvent]),
+ 'onresize' : _callable([Event]),
+ 'onscroll' : _callable([MouseEvent]),
+ 'onselect' : _callable([MouseEvent]),
+ 'onsubmit' : _callable([MouseEvent]),
+ 'onunload' : _callable([Event]),
}
+lambda_returning_true = _callable([Event])
+
EventTarget._methods = {
- 'addEventListener' : MethodDesc(["aa", lambda : None, True]),
- 'dispatchEvent' : MethodDesc(["aa"], True),
- 'removeEventListener' : MethodDesc(["aa", lambda : None, True]),
+ 'addEventListener' : MethodDesc([str, lambda_returning_true]),
+ 'dispatchEvent' : MethodDesc([str], bool),
+ 'removeEventListener' : MethodDesc([str, lambda_returning_true]),
}
Node._fields = EventTarget._fields.copy()
Node._fields.update({
- 'childNodes' : [Element()],
- 'firstChild' : Element(),
- 'lastChild' : Element(),
- 'localName' : "aa",
- 'name' : "aa",
- 'namespaceURI' : "aa",
- 'nextSibling' : Element(),
- 'nodeName' : "aa",
- 'nodeType' : 1,
- 'nodeValue' : "aa",
- 'ownerDocument' : Document(),
- 'parentNode' : Element(),
- 'prefix' : "aa",
- 'previousSibling': Element(),
- 'tagName' : "aa",
- 'textContent' : "aa",
+ 'childNodes' : [Element],
+ 'firstChild' : Element,
+ 'lastChild' : Element,
+ 'localName' : str,
+ 'name' : str,
+ 'namespaceURI' : str,
+ 'nextSibling' : Element,
+ 'nodeName' : str,
+ 'nodeType' : int,
+ 'nodeValue' : str,
+ 'ownerDocument' : Document,
+ 'parentNode' : Element,
+ 'prefix' : str,
+ 'previousSibling': Element,
+ 'tagName' : str,
+ 'textContent' : str,
})
Node._methods = EventTarget._methods.copy()
Node._methods.update({
- 'appendChild' : MethodDesc([Element()]),
- 'cloneNode' : MethodDesc([12], Element()),
- 'getElementsByTagName' : MethodDesc(["aa"], [Element(),
- Element()]),
- 'hasChildNodes' : MethodDesc([], True),
- 'insertBefore' : MethodDesc([Element(), Element()], Element()),
+ 'appendChild' : MethodDesc([Element]),
+ 'cloneNode' : MethodDesc([int], Element),
+ 'getElementsByTagName' : MethodDesc([str], [Element]),
+ 'hasChildNodes' : MethodDesc([], bool),
+ 'insertBefore' : MethodDesc([Element], Element),
'normalize' : MethodDesc([]),
- 'removeChild' : MethodDesc([Element()], Element()),
- 'replaceChild' : MethodDesc([Element(), Element()], Element()),
+ 'removeChild' : MethodDesc([Element]),
+ 'replaceChild' : MethodDesc([Element], Element),
})
Element._fields = Node._fields.copy()
Element._fields.update({
- 'attributes' : [Attribute()],
- 'className' : "aa",
- 'clientHeight' : 12,
- 'clientWidth' : 12,
- 'clientLeft' : 12,
- 'clientTop' : 12,
- 'dir' : "aa",
- 'innerHTML' : "asd",
- 'id' : "aa",
- 'lang' : "asd",
- 'offsetHeight' : 12,
- 'offsetLeft' : 12,
- 'offsetParent' : 12,
- 'offsetTop' : 12,
- 'offsetWidth' : 12,
- 'scrollHeight' : 12,
- 'scrollLeft' : 12,
- 'scrollTop' : 12,
- 'scrollWidth' : 12,
+ 'attributes' : [Attribute],
+ 'className' : str,
+ 'clientHeight' : int,
+ 'clientWidth' : int,
+ 'clientLeft' : int,
+ 'clientTop' : int,
+ 'dir' : str,
+ 'innerHTML' : str,
+ 'id' : str,
+ 'lang' : str,
+ 'offsetHeight' : int,
+ 'offsetLeft' : int,
+ 'offsetParent' : int,
+ 'offsetTop' : int,
+ 'offsetWidth' : int,
+ 'scrollHeight' : int,
+ 'scrollLeft' : int,
+ 'scrollTop' : int,
+ 'scrollWidth' : int,
# HTML specific
- 'style' : Style(),
- 'tabIndex' : 12,
+ 'style' : Style,
+ 'tabIndex' : int,
# XXX: From HTMLInputElement to make pythonconsole work.
- 'value': 'aa',
+ 'value': str,
})
Element._methods = Node._methods.copy()
Element._methods.update({
- 'getAttribute' : MethodDesc(["aa"], "aa"),
- 'getAttributeNS' : MethodDesc(["aa", "aa"], "aa"),
- 'getAttributeNode' : MethodDesc(["aa"], Element()),
- 'getAttributeNodeNS' : MethodDesc(["aa", "aa"], Element()),
- 'hasAttribute' : MethodDesc(["aa"], True),
- 'hasAttributeNS' : MethodDesc(["aa", "aa"], True),
- 'hasAttributes' : MethodDesc([], True),
- 'removeAttribute' : MethodDesc(['aa']),
- 'removeAttributeNS' : MethodDesc(["aa", "aa"]),
- 'removeAttributeNode' : MethodDesc([Element()], "aa"),
- 'setAttribute' : MethodDesc(["aa", "aa"]),
- 'setAttributeNS' : MethodDesc(["aa", "aa", "aa"]),
- 'setAttributeNode' : MethodDesc([Element()], Element()),
- 'setAttributeNodeNS' : MethodDesc(["ns", Element()], Element()),
+ 'getAttribute' : MethodDesc([str], str),
+ 'getAttributeNS' : MethodDesc([str], str),
+ 'getAttributeNode' : MethodDesc([str], Element),
+ 'getAttributeNodeNS' : MethodDesc([str], Element),
+ 'hasAttribute' : MethodDesc([str], bool),
+ 'hasAttributeNS' : MethodDesc([str], bool),
+ 'hasAttributes' : MethodDesc([], bool),
+ 'removeAttribute' : MethodDesc([str]),
+ 'removeAttributeNS' : MethodDesc([str]),
+ 'removeAttributeNode' : MethodDesc([Element], str),
+ 'setAttribute' : MethodDesc([str]),
+ 'setAttributeNS' : MethodDesc([str]),
+ 'setAttributeNode' : MethodDesc([Element], Element),
+ 'setAttributeNodeNS' : MethodDesc([str, Element], Element),
# HTML specific
'blur' : MethodDesc([]),
'click' : MethodDesc([]),
'focus' : MethodDesc([]),
'scrollIntoView' : MethodDesc([]),
- 'supports' : MethodDesc(["aa", 1.0]),
+ 'supports' : MethodDesc([str, float]),
})
Document._fields = Node._fields.copy()
Document._fields.update({
- 'characterSet' : "aa",
+ 'characterSet' : str,
# 'contentWindow' : Window(), XXX doesn't exist, only on iframe
- 'doctype' : "aa",
- 'documentElement' : Element(),
- 'styleSheets' : [Style(), Style()],
- 'alinkColor' : "aa",
- 'bgColor' : "aa",
- 'body' : Element(),
- 'cookie' : "aa",
- 'defaultView' : Window(),
- 'domain' : "aa",
- 'embeds' : [Element(), Element()],
- 'fgColor' : "aa",
- 'forms' : [Element(), Element()],
- 'height' : 123,
- 'images' : [Element(), Element()],
- 'lastModified' : "aa",
- 'linkColor' : "aa",
- 'links' : [Element(), Element()],
- 'location' : "aa",
- 'referrer' : "aa",
- 'title' : "aa",
- 'URL' : "aa",
- 'vlinkColor' : "aa",
- 'width' : 123,
+ 'doctype' : str,
+ 'documentElement' : Element,
+ 'styleSheets' : [Style],
+ 'alinkColor' : str,
+ 'bgColor' : str,
+ 'body' : Element,
+ 'cookie' : str,
+ 'defaultView' : Window,
+ 'domain' : str,
+ 'embeds' : [Element],
+ 'fgColor' : str,
+ 'forms' : [Element],
+ 'height' : int,
+ 'images' : [Element],
+ 'lastModified' : str,
+ 'linkColor' : str,
+ 'links' : [Element],
+ 'location' : str,
+ 'referrer' : str,
+ 'title' : str,
+ 'URL' : str,
+ 'vlinkColor' : str,
+ 'width' : int,
})
Document._methods = Node._methods.copy()
Document._methods.update({
- 'createAttribute' : MethodDesc(["aa"], Element()),
- 'createDocumentFragment' : MethodDesc([], Element()),
- 'createElement' : MethodDesc(["aa"], Element()),
- 'createElementNS' : MethodDesc(["aa", "aa"], Element()),
- 'createEvent' : MethodDesc(["aa"], Event()),
- 'createTextNode' : MethodDesc(["aa"], Element()),
+ 'createAttribute' : MethodDesc([str], Element),
+ 'createDocumentFragment' : MethodDesc([], Element),
+ 'createElement' : MethodDesc([str], Element),
+ 'createElementNS' : MethodDesc([str], Element),
+ 'createEvent' : MethodDesc([str], Event),
+ 'createTextNode' : MethodDesc([str], Element),
#'createRange' : MethodDesc(["aa"], Range()) - don't know what to do here
- 'getElementById' : MethodDesc(["aa"], Element()),
- 'getElementsByName' : MethodDesc(["aa"], [Element(), Element()]),
- 'importNode' : MethodDesc([Element(), True], Element()),
+ 'getElementById' : MethodDesc([str], Element),
+ 'getElementsByName' : MethodDesc([str], [Element]),
+ 'importNode' : MethodDesc([Element, bool], Element),
'clear' : MethodDesc([]),
'close' : MethodDesc([]),
'open' : MethodDesc([]),
- 'write' : MethodDesc(["aa"]),
- 'writeln' : MethodDesc(["aa"]),
+ 'write' : MethodDesc([str]),
+ 'writeln' : MethodDesc([str]),
})
Window._fields = EventTarget._fields.copy()
Window._fields.update({
- 'content' : Window(),
- 'closed' : True,
+ 'content' : Window,
+ 'closed' : bool,
# 'crypto' : Crypto() - not implemented in Gecko, leave alone
- 'defaultStatus' : "aa",
- 'document' : Document(),
+ 'defaultStatus' : str,
+ 'document' : Document,
# 'frameElement' : - leave alone
- 'frames' : [Window(), Window()],
- 'history' : ["aa", "aa"],
- 'innerHeight' : 123,
- 'innerWidth' : 123,
- 'length' : 12,
- 'location' : "aa",
- 'name' : "aa",
+ 'frames' : [Window],
+ 'history' : [str],
+ 'innerHeight' : int,
+ 'innerWidth' : int,
+ 'length' : int,
+ 'location' : str,
+ 'name' : str,
# 'preference' : # denied in gecko
- 'opener' : Window(),
- 'outerHeight' : 123,
- 'outerWidth' : 123,
- 'pageXOffset' : 12,
- 'pageYOffset' : 12,
- 'parent' : Window(),
+ 'opener' : Window,
+ 'outerHeight' : int,
+ 'outerWidth' : int,
+ 'pageXOffset' : int,
+ 'pageYOffset' : int,
+ 'parent' : Window,
# 'personalbar' : - disallowed
# 'screen' : Screen() - not part of the standard, allow it if you want
- 'screenX' : 12,
- 'screenY' : 12,
- 'scrollMaxX' : 12,
- 'scrollMaxY' : 12,
- 'scrollX' : 12,
- 'scrollY' : 12,
- 'self' : Window(),
- 'status' : "asd",
- 'top' : Window(),
- 'window' : Window(),
+ 'screenX' : int,
+ 'screenY' : int,
+ 'scrollMaxX' : int,
+ 'scrollMaxY' : int,
+ 'scrollX' : int,
+ 'scrollY' : int,
+ 'self' : Window,
+ 'status' : str,
+ 'top' : Window,
+ 'window' : Window,
})
Window._methods = Node._methods.copy()
Window._methods.update({
- 'alert' : MethodDesc(["aa"]),
- 'atob' : MethodDesc(["aa"], "aa"),
+ 'alert' : MethodDesc([str]),
+ 'atob' : MethodDesc([str], str),
'back' : MethodDesc([]),
'blur' : MethodDesc([]),
- 'btoa' : MethodDesc(["aa"], "aa"),
+ 'btoa' : MethodDesc([str], str),
'close' : MethodDesc([]),
- 'confirm' : MethodDesc(["aa"], True),
- 'dump' : MethodDesc(["aa"]),
- 'escape' : MethodDesc(["aa"], "aa"),
+ 'confirm' : MethodDesc([str], bool),
+ 'dump' : MethodDesc([str]),
+ 'escape' : MethodDesc([str], str),
#'find' : MethodDesc(["aa"], - gecko only
'focus' : MethodDesc([]),
'forward' : MethodDesc([]),
- 'getComputedStyle' : MethodDesc([Element(), "aa"], Style()),
+ 'getComputedStyle' : MethodDesc([Element, str], Style),
'home' : MethodDesc([]),
- 'open' : MethodDesc(["aa", "aa"]),
+ 'open' : MethodDesc([str]),
})
Style._fields = {
- 'azimuth' : 'aa',
- 'background' : 'aa',
- 'backgroundAttachment' : 'aa',
- 'backgroundColor' : 'aa',
- 'backgroundImage' : 'aa',
- 'backgroundPosition' : 'aa',
- 'backgroundRepeat' : 'aa',
- 'border' : 'aa',
- 'borderBottom' : 'aa',
- 'borderBottomColor' : 'aa',
- 'borderBottomStyle' : 'aa',
- 'borderBottomWidth' : 'aa',
- 'borderCollapse' : 'aa',
- 'borderColor' : 'aa',
- 'borderLeft' : 'aa',
- 'borderLeftColor' : 'aa',
- 'borderLeftStyle' : 'aa',
- 'borderLeftWidth' : 'aa',
- 'borderRight' : 'aa',
- 'borderRightColor' : 'aa',
- 'borderRightStyle' : 'aa',
- 'borderRightWidth' : 'aa',
- 'borderSpacing' : 'aa',
- 'borderStyle' : 'aa',
- 'borderTop' : 'aa',
- 'borderTopColor' : 'aa',
- 'borderTopStyle' : 'aa',
- 'borderTopWidth' : 'aa',
- 'borderWidth' : 'aa',
- 'bottom' : 'aa',
- 'captionSide' : 'aa',
- 'clear' : 'aa',
- 'clip' : 'aa',
- 'color' : 'aa',
- 'content' : 'aa',
- 'counterIncrement' : 'aa',
- 'counterReset' : 'aa',
- 'cssFloat' : 'aa',
- 'cssText' : 'aa',
- 'cue' : 'aa',
- 'cueAfter' : 'aa',
- 'onBefore' : 'aa',
- 'cursor' : 'aa',
- 'direction' : 'aa',
- 'displays' : 'aa',
- 'elevation' : 'aa',
- 'emptyCells' : 'aa',
- 'font' : 'aa',
- 'fontFamily' : 'aa',
- 'fontSize' : 'aa',
- 'fontSizeAdjust' : 'aa',
- 'fontStretch' : 'aa',
- 'fontStyle' : 'aa',
- 'fontVariant' : 'aa',
- 'fontWeight' : 'aa',
- 'height' : 'aa',
- 'left' : 'aa',
- 'length' : 'aa',
- 'letterSpacing' : 'aa',
- 'lineHeight' : 'aa',
- 'listStyle' : 'aa',
- 'listStyleImage' : 'aa',
- 'listStylePosition' : 'aa',
- 'listStyleType' : 'aa',
- 'margin' : 'aa',
- 'marginBottom' : 'aa',
- 'marginLeft' : 'aa',
- 'marginRight' : 'aa',
- 'marginTop' : 'aa',
- 'markerOffset' : 'aa',
- 'marks' : 'aa',
- 'maxHeight' : 'aa',
- 'maxWidth' : 'aa',
- 'minHeight' : 'aa',
- 'minWidth' : 'aa',
- 'MozBinding' : 'aa',
- 'MozOpacity' : 'aa',
- 'orphans' : 'aa',
- 'outline' : 'aa',
- 'outlineColor' : 'aa',
- 'outlineStyle' : 'aa',
- 'outlineWidth' : 'aa',
- 'overflow' : 'aa',
- 'padding' : 'aa',
- 'paddingBottom' : 'aa',
- 'paddingLeft' : 'aa',
- 'paddingRight' : 'aa',
- 'paddingTop' : 'aa',
- 'page' : 'aa',
- 'pageBreakAfter' : 'aa',
- 'pageBreakBefore' : 'aa',
- 'pageBreakInside' : 'aa',
- 'parentRule' : 'aa',
- 'pause' : 'aa',
- 'pauseAfter' : 'aa',
- 'pauseBefore' : 'aa',
- 'pitch' : 'aa',
- 'pitchRange' : 'aa',
- 'playDuring' : 'aa',
- 'position' : 'aa',
- 'quotes' : 'aa',
- 'richness' : 'aa',
- 'right' : 'aa',
- 'size' : 'aa',
- 'speak' : 'aa',
- 'speakHeader' : 'aa',
- 'speakNumeral' : 'aa',
- 'speakPunctuation' : 'aa',
- 'speechRate' : 'aa',
- 'stress' : 'aa',
- 'tableLayout' : 'aa',
- 'textAlign' : 'aa',
- 'textDecoration' : 'aa',
- 'textIndent' : 'aa',
- 'textShadow' : 'aa',
- 'textTransform' : 'aa',
- 'top' : 'aa',
- 'unicodeBidi' : 'aa',
- 'verticalAlign' : 'aa',
- 'visibility' : 'aa',
- 'voiceFamily' : 'aa',
- 'volume' : 'aa',
- 'whiteSpace' : 'aa',
- 'widows' : 'aa',
- 'width' : 'aa',
- 'wordSpacing' : 'aa',
- 'zIndex' : 'aa',
+ 'azimuth' : str,
+ 'background' : str,
+ 'backgroundAttachment' : str,
+ 'backgroundColor' : str,
+ 'backgroundImage' : str,
+ 'backgroundPosition' : str,
+ 'backgroundRepeat' : str,
+ 'border' : str,
+ 'borderBottom' : str,
+ 'borderBottomColor' : str,
+ 'borderBottomStyle' : str,
+ 'borderBottomWidth' : str,
+ 'borderCollapse' : str,
+ 'borderColor' : str,
+ 'borderLeft' : str,
+ 'borderLeftColor' : str,
+ 'borderLeftStyle' : str,
+ 'borderLeftWidth' : str,
+ 'borderRight' : str,
+ 'borderRightColor' : str,
+ 'borderRightStyle' : str,
+ 'borderRightWidth' : str,
+ 'borderSpacing' : str,
+ 'borderStyle' : str,
+ 'borderTop' : str,
+ 'borderTopColor' : str,
+ 'borderTopStyle' : str,
+ 'borderTopWidth' : str,
+ 'borderWidth' : str,
+ 'bottom' : str,
+ 'captionSide' : str,
+ 'clear' : str,
+ 'clip' : str,
+ 'color' : str,
+ 'content' : str,
+ 'counterIncrement' : str,
+ 'counterReset' : str,
+ 'cssFloat' : str,
+ 'cssText' : str,
+ 'cue' : str,
+ 'cueAfter' : str,
+ 'onBefore' : str,
+ 'cursor' : str,
+ 'direction' : str,
+ 'displays' : str,
+ 'elevation' : str,
+ 'emptyCells' : str,
+ 'font' : str,
+ 'fontFamily' : str,
+ 'fontSize' : str,
+ 'fontSizeAdjust' : str,
+ 'fontStretch' : str,
+ 'fontStyle' : str,
+ 'fontVariant' : str,
+ 'fontWeight' : str,
+ 'height' : str,
+ 'left' : str,
+ 'length' : str,
+ 'letterSpacing' : str,
+ 'lineHeight' : str,
+ 'listStyle' : str,
+ 'listStyleImage' : str,
+ 'listStylePosition' : str,
+ 'listStyleType' : str,
+ 'margin' : str,
+ 'marginBottom' : str,
+ 'marginLeft' : str,
+ 'marginRight' : str,
+ 'marginTop' : str,
+ 'markerOffset' : str,
+ 'marks' : str,
+ 'maxHeight' : str,
+ 'maxWidth' : str,
+ 'minHeight' : str,
+ 'minWidth' : str,
+ 'MozBinding' : str,
+ 'MozOpacity' : str,
+ 'orphans' : str,
+ 'outline' : str,
+ 'outlineColor' : str,
+ 'outlineStyle' : str,
+ 'outlineWidth' : str,
+ 'overflow' : str,
+ 'padding' : str,
+ 'paddingBottom' : str,
+ 'paddingLeft' : str,
+ 'paddingRight' : str,
+ 'paddingTop' : str,
+ 'page' : str,
+ 'pageBreakAfter' : str,
+ 'pageBreakBefore' : str,
+ 'pageBreakInside' : str,
+ 'parentRule' : str,
+ 'pause' : str,
+ 'pauseAfter' : str,
+ 'pauseBefore' : str,
+ 'pitch' : str,
+ 'pitchRange' : str,
+ 'playDuring' : str,
+ 'position' : str,
+ 'quotes' : str,
+ 'richness' : str,
+ 'right' : str,
+ 'size' : str,
+ 'speak' : str,
+ 'speakHeader' : str,
+ 'speakNumeral' : str,
+ 'speakPunctuation' : str,
+ 'speechRate' : str,
+ 'stress' : str,
+ 'tableLayout' : str,
+ 'textAlign' : str,
+ 'textDecoration' : str,
+ 'textIndent' : str,
+ 'textShadow' : str,
+ 'textTransform' : str,
+ 'top' : str,
+ 'unicodeBidi' : str,
+ 'verticalAlign' : str,
+ 'visibility' : str,
+ 'voiceFamily' : str,
+ 'volume' : str,
+ 'whiteSpace' : str,
+ 'widows' : str,
+ 'width' : str,
+ 'wordSpacing' : str,
+ 'zIndex' : str,
}
Event._fields = {
- 'bubbles': True,
- 'cancelBubble': True,
- 'cancelable': True,
- 'currentTarget': Element(),
- 'detail': 1,
- 'relatedTarget': Element(),
- 'target': Element(),
- 'type': 'aa',
+ 'bubbles': bool,
+ 'cancelBubble': bool,
+ 'cancelable': bool,
+ 'currentTarget': Element,
+ 'detail': int,
+ 'relatedTarget': Element,
+ 'target': Element,
+ 'type': str,
}
Event._methods = {
- 'initEvent': MethodDesc(["aa", True, True]),
+ 'initEvent': MethodDesc([str, bool, bool]),
'preventDefault': MethodDesc([]),
'stopPropagation': MethodDesc([]),
}
KeyEvent._fields = Event._fields.copy()
KeyEvent._fields.update({
- 'keyCode' : 12,
- 'charCode' : 12,
+ 'keyCode' : int,
+ 'charCode' : int,
})
setTimeout.suggested_primitive = True
Modified: pypy/dist/pypy/translator/js/modules/test/test_dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/test/test_dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/test/test_dom.py Sat Jan 13 18:14:07 2007
@@ -371,6 +371,6 @@
if var.startswith('code_'):
# just build it
#def f():
- assert rpython2javascript(sys.modules[__name__], [var], use_pdb=False)
+ assert rpython2javascript(sys.modules[__name__], [var], use_pdb=True)
TRANSLATING = False
From antocuni at codespeak.net Sat Jan 13 18:19:29 2007
From: antocuni at codespeak.net (antocuni at codespeak.net)
Date: Sat, 13 Jan 2007 18:19:29 +0100 (CET)
Subject: [pypy-svn] r36682 - pypy/dist/pypy/doc
Message-ID: <20070113171929.E84DB10074@code0.codespeak.net>
Author: antocuni
Date: Sat Jan 13 18:19:27 2007
New Revision: 36682
Modified:
pypy/dist/pypy/doc/objspace.txt
Log:
missing import in example code.
Modified: pypy/dist/pypy/doc/objspace.txt
==============================================================================
--- pypy/dist/pypy/doc/objspace.txt (original)
+++ pypy/dist/pypy/doc/objspace.txt Sat Jan 13 18:19:27 2007
@@ -318,6 +318,7 @@
Example usage::
$ py.py -o thunk
+ >>>> from pypymagic import thunk
>>>> def f():
... print 'computing...'
... return 6*7
From fijal at codespeak.net Sat Jan 13 18:29:54 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sat, 13 Jan 2007 18:29:54 +0100 (CET)
Subject: [pypy-svn] r36684 - in pypy/dist/pypy/translator/js: . demo/jsdemo
examples modules modules/test test
Message-ID: <20070113172954.46EE510074@code0.codespeak.net>
Author: fijal
Date: Sat Jan 13 18:29:51 2007
New Revision: 36684
Modified:
pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
pypy/dist/pypy/translator/js/demo/jsdemo/example.py
pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
pypy/dist/pypy/translator/js/examples/start_bnb.py
pypy/dist/pypy/translator/js/modules/dom.py
pypy/dist/pypy/translator/js/modules/test/test_dom.py
pypy/dist/pypy/translator/js/support.py
pypy/dist/pypy/translator/js/test/test_bltn.py
Log:
Wack a bit more here and there. Right now almost all tests passes here.
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Sat Jan 13 18:29:51 2007
@@ -11,6 +11,8 @@
PMSG_INLINE_FRAME, PMSG_DEF_ICON
from pypy.translator.js.demo.jsdemo.msgstruct import *
from cherrypy import session
+from pypy.annotation import model as annmodel
+from pypy.annotation.signature import annotation
import re, time, sys, os, urllib, socket, copy, md5, random
@@ -67,6 +69,8 @@
self.seen = set()
return to_ret
+lambda_None = annmodel.SomeGenericCallable([], result=annotation(None))
+
# Needed double inheritance for both server job
# and semi-transparent communication proxy
class BnbRoot(Root, BasicExternal):
@@ -87,12 +91,12 @@
_render_xmlhttp = True
_methods = {
- 'get_message' : MethodDesc( [('player_id', -1), ('keys' , "aaa"), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}),
- 'add_player' : MethodDesc( [('player_id', 0), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}),
- 'remove_player': MethodDesc( [('player_id', 0), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}),
- 'player_name' : MethodDesc( [('player_id', 0), ('name', 'PyPy player'), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}),
+ 'get_message' : MethodDesc( [('player_id', int), ('keys' , str), ('callback', lambda_None)] , {str:[{str:str}]}),
+ 'add_player' : MethodDesc( [('player_id', int), ('callback', lambda_None)] , {str:[{str:str}]}),
+ 'remove_player': MethodDesc( [('player_id', int), ('callback', lambda_None)] , {str:[{str:str}]}),
+ 'player_name' : MethodDesc( [('player_id', int), ('name', str), ('callback', lambda_None)] , {str:[{str:str}]}),
# 'key' : MethodDesc( [('player_id', 0), ('keynum', '0'), ('callback', (lambda : None))] , {'aa':[{'aa':'bb'}]}),
- 'initialize_session' : MethodDesc( [('callback', (lambda : None))], {'aa':'bb'}),
+ 'initialize_session' : MethodDesc( [('callback', lambda_None)], {str:str}),
}
def add_player(self, player_id = 0):
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/example.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/example.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/example.py Sat Jan 13 18:29:51 2007
@@ -9,6 +9,8 @@
from pypy.translator.js.modules.dom import setTimeout, document
from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal
from pypy.translator.js import commproxy
+from pypy.annotation import model as annmodel
+from pypy.annotation.signature import annotation
commproxy.USE_MOCHIKIT = False
@@ -37,10 +39,12 @@
def runjs():
httpd.some_callback(callback)
+lambda_None = annmodel.SomeGenericCallable([], result=annotation(None))
+
class Server(HTTPServer, BasicExternal):
# Methods and signatures how they are rendered for JS
_methods = {
- 'some_callback' : MethodDesc([('callback', lambda : None)], {'aa':'aa'})
+ 'some_callback' : MethodDesc([('callback', lambda_None)], {str:str})
}
_render_xmlhttp = True
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Sat Jan 13 18:29:51 2007
@@ -16,6 +16,10 @@
from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal
from pypy.translator.js import commproxy
from pypy.translator.js.modules.mochikit import escapeHTML
+from pypy.annotation import model as annmodel
+from pypy.annotation.signature import annotation
+
+lambda_None = annmodel.SomeGenericCallable([], result=annotation(None))
from pypy.translator.js.demo.jsdemo import support
@@ -91,9 +95,9 @@
class Server(HTTPServer, BasicExternal):
# Methods and signatures how they are rendered for JS
_methods = {
- 'some_callback' : MethodDesc([('cmd', "aa"),
- ('callback', lambda : None)],
- {'aa': 'aa'})
+ 'some_callback' : MethodDesc([('cmd', str),
+ ('callback', lambda_None)],
+ {str:str})
}
_render_xmlhttp = True
Modified: pypy/dist/pypy/translator/js/examples/start_bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/start_bnb.py (original)
+++ pypy/dist/pypy/translator/js/examples/start_bnb.py Sat Jan 13 18:29:51 2007
@@ -13,9 +13,7 @@
from pypy.translator.js.test.runtest import compile_function
from pypy.translator.js.modules.dom import document
-from pypy.translator.js.modules.xmlhttp import XMLHttpRequest
from pypy.translator.js.modules.mochikit import log, logWarning, createLoggingPane, logDebug
-from pypy.translator.js.modules.bltns import date
from pypy.translator.js.demo.jsdemo.bnb import BnbRootInstance
import time
@@ -41,7 +39,7 @@
def register_frame(self):
self.n_rendered_inline_frames += 1
if self.n_rendered_inline_frames >= 10:
- next_time = date()
+ next_time = time.time()
self.fps = 10000/(next_time - self.starttime)
self.n_rendered_inline_frames = 0
self.starttime = next_time
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Sat Jan 13 18:29:51 2007
@@ -26,6 +26,7 @@
from pypy.annotation.signature import annotation
from pypy.annotation import model as annmodel
+from pypy.translator.js.support import _callable
# EventTarget is the base class for Nodes and Window
class EventTarget(BasicExternal):
@@ -314,10 +315,6 @@
# rtyper stuff
-def _callable(args, result=None):
- return annmodel.SomeGenericCallable([annotation(i) for i in args],
- annotation(result))
-
EventTarget._fields = {
'onabort' : _callable([Event]),
'onblur' : _callable([Event]),
Modified: pypy/dist/pypy/translator/js/modules/test/test_dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/test/test_dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/test/test_dom.py Sat Jan 13 18:29:51 2007
@@ -371,6 +371,6 @@
if var.startswith('code_'):
# just build it
#def f():
- assert rpython2javascript(sys.modules[__name__], [var], use_pdb=True)
+ assert rpython2javascript(sys.modules[__name__], [var], use_pdb=False)
TRANSLATING = False
Modified: pypy/dist/pypy/translator/js/support.py
==============================================================================
--- pypy/dist/pypy/translator/js/support.py (original)
+++ pypy/dist/pypy/translator/js/support.py Sat Jan 13 18:29:51 2007
@@ -1,6 +1,13 @@
from pypy.translator.gensupp import NameManager
#from pypy.translator.js.optimize import is_optimized_function
+from pypy.annotation.signature import annotation
+from pypy.annotation import model as annmodel
+
+def _callable(args, result=None):
+ return annmodel.SomeGenericCallable([annotation(i) for i in args],
+ annotation(result))
+
class JavascriptNameManager(NameManager):
def __init__(self, db):
NameManager.__init__(self)
Modified: pypy/dist/pypy/translator/js/test/test_bltn.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_bltn.py (original)
+++ pypy/dist/pypy/translator/js/test/test_bltn.py Sat Jan 13 18:29:51 2007
@@ -5,6 +5,7 @@
from pypy.rpython.ootypesystem.bltregistry import BasicExternal, MethodDesc
from pypy.translator.js.test.runtest import compile_function, check_source_contains
+from pypy.translator.js.support import _callable
# check rendering dom.document
def test_simple_builtin():
@@ -21,12 +22,12 @@
_render_xmlhttp = True
_methods = {
- 'some_method' : MethodDesc([], 3),
+ 'some_method' : MethodDesc([], int),
}
class SomeNode(BasicExternal):
_fields = {
- 'some_callback' : MethodDesc([3], 3),
+ 'some_callback' : _callable([int], int),
}
SomeProxyInstance = SomeProxy()
From santagada at codespeak.net Sat Jan 13 18:45:38 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Sat, 13 Jan 2007 18:45:38 +0100 (CET)
Subject: [pypy-svn] r36686 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070113174538.0FC9910077@code0.codespeak.net>
Author: santagada
Date: Sat Jan 13 18:45:36 2007
New Revision: 36686
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
the world would be a better place without javascript... but now we even have somewhat working prototypes!! (I really mean it this time)
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Sat Jan 13 18:45:36 2007
@@ -70,13 +70,34 @@
class Interpreter(object):
"""Creates a js interpreter"""
def __init__(self):
- self.w_Object = W_Object() #creating Object
- self.w_Global = W_Object()
- self.w_Global.Prototype = self.w_Object
- self.w_Global.Put('prototype', W_String('Object'))
- self.w_Global.Put('Object', self.w_Object)
- self.global_context = global_context(self.w_Global)
- self.w_Global.Put('eval', W_Builtin(evaljs, context=True, args=1))
+ w_Global = W_Object()
+ ctx = global_context(w_Global)
+
+ w_ObjPrototype = W_Object(Prototype=None, Class='Object')
+
+ #Function stuff
+ w_Function = W_Object(ctx=ctx, Class='Function',
+ Prototype=w_ObjPrototype)
+ w_Function.Put('prototype', w_Function, dd=True, de=True, ro=True)
+ w_Function.Put('constructor', w_Function)
+
+ #Object stuff
+ w_Object = W_Object(Prototype=w_Function)
+ w_Object.Put('length', W_Number(1), ro=True, dd=True)
+ w_Object.Put('prototype', w_ObjPrototype, dd=True, de=True, ro=True)
+ w_ObjPrototype.Put('constructor', w_Object)
+ #And some other stuff
+
+ w_Array = W_Array([])
+ w_Global.Put('prototype', W_String('Object'))
+ w_Global.Put('Object', w_Object)
+ w_Global.Put('Function', w_Function)
+ w_Global.Put('Array', w_Array)
+ w_Global.Put('eval', W_Builtin(evaljs, context=True, args=1))
+
+ self.global_context = ctx
+ self.w_Global = w_Global
+ self.w_Object = w_Object
def run(self, script):
"""run the interpreter"""
@@ -194,7 +215,7 @@
self.body = body
def eval(self, ctx):
- w_obj = W_FunctionObject(self, ctx)
+ w_obj = W_Object(ctx=ctx, callfunc = self)
return w_obj
class Identifier(Expression):
@@ -368,16 +389,16 @@
return W_Number(x - y)
class New(Expression):
- def __init__(self, identifier):
- self.identifier = identifier
+ def __init__(self, newexpr):
+ self.newexpr = newexpr
def eval(self, ctx):
- obj = W_Object()
- #it should be undefined... to be completed
- constructor = ctx.resolve_identifier(self.identifier).GetValue()
- obj.Put('prototype', constructor.Get('prototype'))
- constructor.Call(ctx, this = obj)
- return obj
+ x = self.newexpr.eval(ctx).GetValue()
+ if not isinstance(x, W_Object):
+ raise TypeError()
+
+ return x.Construct(ctx=ctx)
+
class Number(Expression):
def __init__(self, num):
@@ -672,7 +693,7 @@
elif tp == 'NE':
node = Ne(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NEW':
- node = New(gettreeitem(gettreeitem(t, '0'),'value').additional_info)
+ node = New(from_tree(gettreeitem(t, '0')))
elif tp == 'NUMBER':
node = Number(float(gettreeitem(t, 'value').additional_info))
elif tp == 'OBJECT_INIT':
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Sat Jan 13 18:45:36 2007
@@ -18,22 +18,24 @@
class JsTypeError(Exception):
pass
-INFDEF = 1e300 * 1e300
-NaN = INFDEF/INFDEF
+INF = 1e300 * 1e300
+MINF = -INF
+NaN = INF/INF
+
class Property(object):
- def __init__(self, name, value, DontDelete=False,
- ReadOnly=False, DontEnum=False, Internal=False):
+ def __init__(self, name, value, dd=False,
+ ro=False, de=False, it=False):
self.name = name
self.value = value
- self.DontDelete = DontDelete
- self.ReadOnly = ReadOnly
- self.DontEnum = DontEnum
- self.Internal = Internal
+ self.dd = dd
+ self.ro = ro
+ self.de = de
+ self.it = it
def __repr__(self):
- return "|%s %d%d%d|"%(self.value, self.DontDelete,
- self.ReadOnly, self.DontEnum)
+ return "|%s %d%d%d|"%(self.value, self.dd,
+ self.ro, self.de)
def internal_property(name, value):
"""return a internal property with the right attributes"""
@@ -61,8 +63,8 @@
def Get(self, P):
raise NotImplementedError
- def Put(self, P, V, DontDelete=False,
- ReadOnly=False, DontEnum=False, Internal=False):
+ def Put(self, P, V, dd=False,
+ ro=False, de=False, it=False):
raise NotImplementedError
def PutValue(self, w, ctx):
@@ -78,7 +80,40 @@
return "<%s(%s)>" % (self.__class__.__name__, self.ToString())
def type(self):
- return NotImplementedError
+ raise NotImplementedError
+
+ def delete(self):
+ raise NotImplementedError
+
+class W_Undefined(W_Root):
+ def __str__(self):
+ return "w_undefined"
+
+ def ToNumber(self):
+ return NaN
+
+ def ToBoolean(self):
+ return False
+
+ def ToString(self):
+ return "undefined"
+
+ def type(self):
+ return 'undefined'
+
+class W_Null(W_Root):
+ def __str__(self):
+ return "null"
+
+ def ToBoolean(self):
+ return False
+
+ def type(self):
+ return 'object'
+
+w_Undefined = W_Undefined()
+w_Null = W_Null()
+
class W_Primitive(W_Root):
"""unifying parent for primitives"""
@@ -86,19 +121,54 @@
return self
class W_Object(W_Root):
- def __init__(self):
+ def __init__(self, ctx=None, Prototype=None, Class='Object',
+ Value=w_Undefined, callfunc=None):
self.propdict = {}
self.propdict['toString'] = Property('toString',
W_Builtin(self.__str__))
self.propdict['prototype'] = Property('prototype', w_Undefined,
- DontDelete=True)
- self.Prototype = None
- self.Class = "Object"
- self.scope = []
-
- def Call(self, ctx, args=[], this = None):
- return W_Object()
+ dd=True)
+ self.Prototype = Prototype
+ self.Class = Class
+ self.callfunc = callfunc
+ if callfunc is not None:
+ self.Scope = ctx.scope[:]
+ else:
+ self.Scope = []
+ self.Value = Value
+
+ def Call(self, ctx, args=[], this=None):
+ act = ActivationObject()
+ for i in range(len(self.callfunc.params)):
+ arg = self.callfunc.params[i]
+ try:
+ value = args[i]
+ except IndexError:
+ value = w_Undefined
+ act.Put(self.callfunc.params[i], value)
+ act.Put('this', this)
+ w_Arguments = W_Arguments(self, args)
+ act.Put('arguments', w_Arguments)
+ newctx = function_context(self.Scope, act, this)
+ val = self.callfunc.body.execute(ctx=newctx)
+ return val
+ def Construct(self, ctx, args=[]):
+ if self.callfunc is None:
+ raise TypeError()
+ obj = W_Object(Class='Object')
+ prot = self.Get('prototype')
+ if isinstance(prot, W_Object):
+ obj.Prototype = prot
+ else:
+ obj.Prototype = ctx.get_global().Get('Object')
+ ret = self.Call(ctx, args, this=obj)
+ if isinstance(ret, W_Object):
+ return ret
+ else:
+ return obj
+
+
def Get(self, P):
if P in self.propdict: return self.propdict[P].value
if self.Prototype is None: return w_Undefined
@@ -106,18 +176,20 @@
def CanPut(self, P):
if P in self.propdict:
- if self.propdict[P].ReadOnly: return False
+ if self.propdict[P].ro: return False
return True
if self.Prototype is None: return True
return self.Prototype.CanPut(P)
- def Put(self, P, V):
+ def Put(self, P, V, dd=False,
+ ro=False, de=False, it=False):
if not self.CanPut(P):
return
if P in self.propdict:
self.propdict[P].value = V
else:
- self.propdict[P] = Property(P, V)
+ self.propdict[P] = Property(P, V,
+ dd = dd, ro = ro, it = it)
def HasProperty(self, P):
if P in self.propdict: return True
@@ -126,7 +198,7 @@
def Delete(P):
if P in self.propdict:
- if self.propdict[P].DontDelete: return False
+ if self.propdict[P].dd: return False
del self.propdict[P]
return True
return True
@@ -159,64 +231,29 @@
return "" % self.Class
def type(self):
- #if implements call its function
- return 'object'
+ if callfunc is not none:
+ return 'function'
+ else:
+ return 'object'
class W_Arguments(W_Object):
def __init__(self, callee, args):
- W_Object.__init__(self)
- self.Class = "arguments"
+ W_Object.__init__(self, Class='Arguments')
del self.propdict["toString"]
del self.propdict["prototype"]
self.Put('callee', callee)
self.Put('length', W_Number(len(args)))
-## for i, arg in enumerate(args):
-## self.Put(str(i), arg)
for i in range(len(args)):
self.Put(str(i), args[i])
class ActivationObject(W_Object):
"""The object used on function calls to hold arguments and this"""
def __init__(self):
- W_Object.__init__(self)
- self.Class = "Activation"
+ W_Object.__init__(self, Class='Activation')
del self.propdict["toString"]
del self.propdict["prototype"]
-class W_FunctionObject(W_Object):
- def __init__(self, function, ctx):
- # TODO: See page 80
- W_Object.__init__(self)
- self.function = function
- self.Class = "Function"
- self.Prototype = None # TODO: See page 95 section 15.3.3.1
- self.scope = ctx.scope[:]
-
- def Call(self, ctx, args=[], this=None):
- #print "* start of function call"
- #print " args = ", args
- act = ActivationObject()
- #for i, arg in enumerate(self.function.params):
- for i in range(len(self.function.params)):
- arg = self.function.params[i]
- try:
- value = args[i]
- except IndexError:
- value = w_Undefined
- act.Put(self.function.params[i], value)
- act.Put('this', this)
- #print " act.propdict = ", act.propdict
- w_Arguments = W_Arguments(self, args)
- act.Put('arguments', w_Arguments)
- newctx = function_context(self.scope, act, this)
- val = self.function.body.execute(ctx=newctx)
- #print "* end of function call return = ", val
- return val
-
- def type(self):
- return 'function'
-
class W_Array(W_Object):
def __init__(self, items):
W_Object.__init__(self)
@@ -236,32 +273,6 @@
# self.propdict['length'].value = W_Number(x)
self.propdict[P] = Property(P, V)
-class W_Undefined(W_Root):
- def __str__(self):
- return "w_undefined"
-
- def ToNumber(self):
- return NaN
-
- def ToBoolean(self):
- return False
-
- def ToString(self):
- return "undefined"
-
- def type(self):
- return 'undefined'
-
-
-class W_Null(W_Root):
- def __str__(self):
- return "null"
-
- def ToBoolean(self):
- return False
-
- def type(self):
- return 'object'
class W_Boolean(W_Primitive):
def __init__(self, boolval):
@@ -358,9 +369,6 @@
def __str__(self):
return str(self.list_w)
-w_Undefined = W_Undefined()
-w_Null = W_Null()
-
class ExecutionContext(object):
def __init__(self):
self.scope = []
@@ -400,7 +408,7 @@
ctx = ExecutionContext()
ctx.push_object(w_global)
ctx.this = w_global
- ctx.property = Property('', w_Undefined, DontDelete=True)
+ ctx.property = Property('', w_Undefined, dd=True)
return ctx
def function_context(scope, activation, this=None):
@@ -412,7 +420,7 @@
else:
ctx.this = this
- ctx.property = Property('', w_Undefined, DontDelete=True)
+ ctx.property = Property('', w_Undefined, dd=True)
return ctx
def eval_context(calling_context):
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Sat Jan 13 18:45:36 2007
@@ -321,8 +321,8 @@
def test_arrayobject(self):
py.test.skip(" TODO: needed for mozilla test suite")
- x= """var testcases = new Array();
- var tc = testcases.length;"""
+ self.assert_prints("""var x = new Array();
+ print(x.length);""", ['0'])
def test_break(self):
self.assert_prints("""
From ericvrp at codespeak.net Sat Jan 13 18:55:44 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 13 Jan 2007 18:55:44 +0100 (CET)
Subject: [pypy-svn] r36687 - in pypy/dist/pypy/jit/codegen: i386/test llvm
llvm/test test
Message-ID: <20070113175544.979B410082@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 13 18:55:43 2007
New Revision: 36687
Modified:
pypy/dist/pypy/jit/codegen/i386/test/test_operation.py
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
fix two tests (cast_bool_to_int) and one annotation problem
Modified: pypy/dist/pypy/jit/codegen/i386/test/test_operation.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/i386/test/test_operation.py (original)
+++ pypy/dist/pypy/jit/codegen/i386/test/test_operation.py Sat Jan 13 18:55:43 2007
@@ -247,14 +247,14 @@
assert fp(40.0, 2.0) == fn(40.0, 2.0)
assert fp(25.125, 1.5) == fn(25.125, 1.5)
- def test_float_pow(self): #harder test for llvm
+ def test_float_pow(self): #harder test for llvm
for fn in [lambda x, y: x ** y, #not supported in llvm backend
]:
fp = self.rgen(fn, [float, float], float)
assert fp(40.0, 2.0) == fn(40.0, 2.0)
assert fp(25.125, 1.5) == fn(25.125, 1.5)
- def test_float_cast(self): #because of differnt rettype
+ def test_float_cast(self): #because of different rettype
for fn in [lambda x: bool(x),
lambda x: bool(x - 2.0),
]:
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Sat Jan 13 18:55:43 2007
@@ -209,6 +209,7 @@
class AddrConst(GenConst):
type = pi8
signed = False
+ addr = llmemory.NULL #have 'addr' even when not instantiated
def __init__(self, addr):
self.addr = addr
@@ -905,7 +906,7 @@
funcsig = gv_fn.operand()
else:
#XXX we probably need to call an address directly if we can't resolve the funcsig
- funcsig = self.rgenop.funcsig[gv_fnptr.value]
+ funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()]
gv_returnvar = Var(restype)
self.asm.append(' %s=call %s(%s)' % (
gv_returnvar.operand2(),
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_rgenop.py Sat Jan 13 18:55:43 2007
@@ -23,5 +23,3 @@
test_goto_direct = skip_too_minimal #segfault
test_goto_compile = skip_too_minimal #segfault
test_fact_direct = skip_too_minimal #segfault
-
- test_fact_compile = skip #XXX Blocked block, (addr = self.addr) in AddrConst.operand2()
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 18:55:43 2007
@@ -683,14 +683,21 @@
gv_eq = builder.genop2("int_eq", gv_x, gv_y)
gv_ne = builder.genop2("int_ne", gv_x, gv_y)
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+ gv_gt1 = builder.genop1("cast_bool_to_int", gv_gt)
+ gv_lt1 = builder.genop1("cast_bool_to_int", gv_lt)
+ gv_ge1 = builder.genop1("cast_bool_to_int", gv_ge)
+ gv_le1 = builder.genop1("cast_bool_to_int", gv_le)
+ gv_eq1 = builder.genop1("cast_bool_to_int", gv_eq)
+ gv_ne1 = builder.genop1("cast_bool_to_int", gv_ne)
+
+ gv_gt2 = gv_gt1
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt1)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge1)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le1)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq1)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne1)
- gv_r0 = gv_gt
+ gv_r0 = gv_gt2
gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
@@ -724,14 +731,21 @@
gv_eq = builder.genop2("int_eq", gv_one, gv_x)
gv_ne = builder.genop2("int_ne", gv_one, gv_x)
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+ gv_gt1 = builder.genop1("cast_bool_to_int", gv_gt)
+ gv_lt1 = builder.genop1("cast_bool_to_int", gv_lt)
+ gv_ge1 = builder.genop1("cast_bool_to_int", gv_ge)
+ gv_le1 = builder.genop1("cast_bool_to_int", gv_le)
+ gv_eq1 = builder.genop1("cast_bool_to_int", gv_eq)
+ gv_ne1 = builder.genop1("cast_bool_to_int", gv_ne)
+
+ gv_gt2 = gv_gt1
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt1)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge1)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le1)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq1)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne1)
- gv_r0 = gv_gt
+ gv_r0 = gv_gt2
gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
From arigo at codespeak.net Sat Jan 13 19:00:58 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 19:00:58 +0100 (CET)
Subject: [pypy-svn] r36688 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113180058.3E41510083@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 19:00:55 2007
New Revision: 36688
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Flexswitches. More small fixes.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 19:00:55 2007
@@ -6,6 +6,7 @@
from pypy.objspace.std.multimethod import FailedToImplement
from pypy.jit.codegen.i386.ri386 import *
from pypy.jit.codegen.i386.ri386setup import Conditions
+from pypy.jit.codegen.i386.codebuf import CodeBlockOverflow
from pypy.jit.codegen.i386 import conftest
@@ -399,6 +400,69 @@
# ____________________________________________________________
+class FlexSwitch(CodeGenSwitch):
+ REG = eax
+
+ def __init__(self, rgenop, inputargs_gv, inputoperands):
+ self.rgenop = rgenop
+ self.inputargs_gv = inputargs_gv
+ self.inputoperands = inputoperands
+ self.defaultcaseaddr = 0
+
+ def initialize(self, mc):
+ self._reserve(mc)
+ default_builder = Builder(self.rgenop, self.inputargs_gv,
+ self.inputoperands)
+ default_builder.set_coming_from(mc)
+ default_builder.update_defaultcaseaddr_of = self
+ default_builder.start_writing()
+ return default_builder
+
+ def _reserve(self, mc):
+ RESERVED = 11*4+5 # XXX quite a lot for now :-/
+ pos = mc.tell()
+ mc.UD2()
+ mc.write('\x00' * (RESERVED-1))
+ self.nextfreepos = pos
+ self.endfreepos = pos + RESERVED
+
+ def _reserve_more(self):
+ start = self.nextfreepos
+ end = self.endfreepos
+ newmc = self.rgenop.open_mc()
+ self._reserve(newmc)
+ self.rgenop.close_mc(newmc)
+ fullmc = self.rgenop.InMemoryCodeBuilder(start, end)
+ fullmc.JMP(rel32(self.nextfreepos))
+ fullmc.done()
+
+ def add_case(self, gv_case):
+ rgenop = self.rgenop
+ targetbuilder = Builder(self.rgenop, self.inputargs_gv,
+ self.inputoperands)
+ try:
+ self._add_case(gv_case, targetbuilder)
+ except CodeBlockOverflow:
+ self._reserve_more()
+ self._add_case(gv_case, targetbuilder)
+ targetbuilder.start_writing()
+ return targetbuilder
+
+ def _add_case(self, gv_case, targetbuilder):
+ start = self.nextfreepos
+ end = self.endfreepos
+ mc = self.rgenop.InMemoryCodeBuilder(start, end)
+ value = gv_case.revealconst(lltype.Signed)
+ mc.CMP(FlexSwitch.REG, imm(value))
+ targetbuilder.set_coming_from(mc, Conditions['E'])
+ pos = mc.tell()
+ assert self.defaultcaseaddr != 0
+ mc.JMP(rel32(self.defaultcaseaddr))
+ mc.done()
+ self.nextfreepos = pos
+
+# ____________________________________________________________
+
def setup_opclasses(base):
d = {}
for name, value in globals().items():
@@ -544,23 +608,24 @@
if at_start:
pass # input variable not used anyway
else:
- self.add_final_move(v, operand)
+ self.add_final_move(v, operand, make_copy=v.is_const)
else:
if loc in force_loc2operand or operand in force_operand2loc:
if at_start:
self.initial_moves.append((loc, operand))
else:
- self.add_final_move(v, operand)
+ self.add_final_move(v, operand, make_copy=True)
else:
force_loc2operand[loc] = operand
force_operand2loc[operand] = loc
- def add_final_move(self, v, targetoperand):
- v2 = OpSameAs(v)
- self.operations.append(v2)
+ def add_final_move(self, v, targetoperand, make_copy):
+ if make_copy:
+ v = OpSameAs(v)
+ self.operations.append(v)
loc = self.nextloc
self.nextloc += 1
- self.var2loc[v2] = loc
+ self.var2loc[v] = loc
self.force_loc2operand[loc] = targetoperand
def allocate_registers(self):
@@ -653,6 +718,7 @@
class Builder(GenBuilder):
coming_from = 0
operations = None
+ update_defaultcaseaddr_of = None
def __init__(self, rgenop, inputargs_gv, inputoperands):
self.rgenop = rgenop
@@ -717,6 +783,8 @@
start = self.coming_from
if start:
targetaddr = mc.tell()
+ if self.update_defaultcaseaddr_of: # hack for FlexSwitch
+ self.update_defaultcaseaddr_of.defaultcaseaddr = targetaddr
end = start + 6 # XXX hard-coded, enough for JMP and Jcond
oldmc = self.rgenop.InMemoryCodeBuilder(start, end)
insn = EMIT_JCOND[self.coming_from_cond]
@@ -797,6 +865,21 @@
self.operations.append(op)
return op
+ def flexswitch(self, gv_exitswitch, args_gv):
+ reg = FlexSwitch.REG
+ mc = self.generate_block_code(args_gv, [gv_exitswitch], [reg],
+ renaming=False)
+ result = FlexSwitch(self.rgenop, self.inputargs_gv, self.inputoperands)
+ default_builder = result.initialize(mc)
+ self.rgenop.close_mc(mc)
+ return result, default_builder
+
+ def show_incremental_progress(self):
+ pass
+
+ def log(self, msg):
+ self.mc.log(msg)
+
class RI386GenOp(AbstractRGenOp):
from pypy.jit.codegen.i386.codebuf import MachineCodeBlock
From arigo at codespeak.net Sat Jan 13 19:13:57 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 19:13:57 +0100 (CET)
Subject: [pypy-svn] r36692 - pypy/dist/pypy/jit/codegen/test
Message-ID: <20070113181357.ABAA310083@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 19:13:56 2007
New Revision: 36692
Modified:
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
Yet another test that fails in the new i386 branch.
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 19:13:56 2007
@@ -795,3 +795,42 @@
res = fnptr(44)
assert res == 2
+
+ def test_jump_to_block_with_many_vars(self):
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_verysmall_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "verysmall")
+ builder.finish_and_return(sigtoken, rgenop.genconst(17))
+
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "jtbwmv")
+ gv_cond = builder.genop1("int_is_true", gv_x)
+ builder2 = builder.jump_if_false(gv_cond, [gv_x])
+ builder = builder.pause_writing([gv_x])
+
+ builder2.start_writing()
+ args_gv = [gv_x]
+ label = builder2.enter_next_block([signed_kind], args_gv)
+ [gv_x2] = args_gv
+
+ gvs = []
+ for i in range(50):
+ gvs.append(builder2.genop2("int_mul", gv_x2, rgenop.genconst(i)))
+
+ gvs.append(builder2.genop_call(sigtoken, gv_verysmall_callable,
+ [gv_x2]))
+
+ while len(gvs) > 1:
+ gvs.append(builder2.genop2("int_add", gvs.pop(), gvs.pop()))
+
+ builder2.finish_and_return(sigtoken, gvs.pop())
+
+ builder.start_writing()
+ builder.finish_and_goto([gv_x], label)
+ builder.end()
+ fnptr = self.cast(gv_callable, 1)
+
+ res = fnptr(1291)
+ assert res == 1291 * (49*50/2) + 17
From arigo at codespeak.net Sat Jan 13 19:14:55 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 19:14:55 +0100 (CET)
Subject: [pypy-svn] r36693 - in pypy/branch/i386-regalloc/pypy/jit/codegen:
i386/test llvm llvm/test test
Message-ID: <20070113181455.CCC0F10088@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 19:14:53 2007
New Revision: 36693
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_operation.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py
pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
Log:
svn merge -r36663:36692 http://codespeak.net/svn/pypy/dist/pypy/jit/codegen
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_operation.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_operation.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/test/test_operation.py Sat Jan 13 19:14:53 2007
@@ -247,14 +247,14 @@
assert fp(40.0, 2.0) == fn(40.0, 2.0)
assert fp(25.125, 1.5) == fn(25.125, 1.5)
- def test_float_pow(self): #harder test for llvm
+ def test_float_pow(self): #harder test for llvm
for fn in [lambda x, y: x ** y, #not supported in llvm backend
]:
fp = self.rgen(fn, [float, float], float)
assert fp(40.0, 2.0) == fn(40.0, 2.0)
assert fp(25.125, 1.5) == fn(25.125, 1.5)
- def test_float_cast(self): #because of differnt rettype
+ def test_float_cast(self): #because of different rettype
for fn in [lambda x: bool(x),
lambda x: bool(x - 2.0),
]:
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/rgenop.py Sat Jan 13 19:14:53 2007
@@ -209,6 +209,7 @@
class AddrConst(GenConst):
type = pi8
signed = False
+ addr = llmemory.NULL #have 'addr' even when not instantiated
def __init__(self, addr):
self.addr = addr
@@ -905,7 +906,7 @@
funcsig = gv_fn.operand()
else:
#XXX we probably need to call an address directly if we can't resolve the funcsig
- funcsig = self.rgenop.funcsig[gv_fnptr.value]
+ funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()]
gv_returnvar = Var(restype)
self.asm.append(' %s=call %s(%s)' % (
gv_returnvar.operand2(),
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/llvm/test/test_rgenop.py Sat Jan 13 19:14:53 2007
@@ -23,5 +23,3 @@
test_goto_direct = skip_too_minimal #segfault
test_goto_compile = skip_too_minimal #segfault
test_fact_direct = skip_too_minimal #segfault
-
- test_fact_compile = skip #XXX Blocked block, (addr = self.addr) in AddrConst.operand2()
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 19:14:53 2007
@@ -754,14 +754,21 @@
gv_eq = builder.genop2("int_eq", gv_x, gv_y)
gv_ne = builder.genop2("int_ne", gv_x, gv_y)
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+ gv_gt1 = builder.genop1("cast_bool_to_int", gv_gt)
+ gv_lt1 = builder.genop1("cast_bool_to_int", gv_lt)
+ gv_ge1 = builder.genop1("cast_bool_to_int", gv_ge)
+ gv_le1 = builder.genop1("cast_bool_to_int", gv_le)
+ gv_eq1 = builder.genop1("cast_bool_to_int", gv_eq)
+ gv_ne1 = builder.genop1("cast_bool_to_int", gv_ne)
+
+ gv_gt2 = gv_gt1
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt1)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge1)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le1)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq1)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne1)
- gv_r0 = gv_gt
+ gv_r0 = gv_gt2
gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
@@ -795,14 +802,21 @@
gv_eq = builder.genop2("int_eq", gv_one, gv_x)
gv_ne = builder.genop2("int_ne", gv_one, gv_x)
- gv_gt2 = gv_gt
- gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt)
- gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge)
- gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le)
- gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq)
- gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne)
+ gv_gt1 = builder.genop1("cast_bool_to_int", gv_gt)
+ gv_lt1 = builder.genop1("cast_bool_to_int", gv_lt)
+ gv_ge1 = builder.genop1("cast_bool_to_int", gv_ge)
+ gv_le1 = builder.genop1("cast_bool_to_int", gv_le)
+ gv_eq1 = builder.genop1("cast_bool_to_int", gv_eq)
+ gv_ne1 = builder.genop1("cast_bool_to_int", gv_ne)
+
+ gv_gt2 = gv_gt1
+ gv_lt2 = builder.genop2("int_mul", rgenop.genconst(10), gv_lt1)
+ gv_ge2 = builder.genop2("int_mul", rgenop.genconst(100), gv_ge1)
+ gv_le2 = builder.genop2("int_mul", rgenop.genconst(1000), gv_le1)
+ gv_eq2 = builder.genop2("int_mul", rgenop.genconst(10000), gv_eq1)
+ gv_ne2 = builder.genop2("int_mul", rgenop.genconst(100000), gv_ne1)
- gv_r0 = gv_gt
+ gv_r0 = gv_gt2
gv_r1 = builder.genop2("int_add", gv_r0, gv_lt2)
gv_r2 = builder.genop2("int_add", gv_r1, gv_ge2)
gv_r3 = builder.genop2("int_add", gv_r2, gv_le2)
@@ -852,3 +866,42 @@
res = fnptr(44)
assert res == 2
+
+ def test_jump_to_block_with_many_vars(self):
+ rgenop = self.RGenOp()
+ signed_kind = rgenop.kindToken(lltype.Signed)
+ sigtoken = rgenop.sigToken(FUNC)
+ builder, gv_verysmall_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "verysmall")
+ builder.finish_and_return(sigtoken, rgenop.genconst(17))
+
+ builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
+ "jtbwmv")
+ gv_cond = builder.genop1("int_is_true", gv_x)
+ builder2 = builder.jump_if_false(gv_cond, [gv_x])
+ builder = builder.pause_writing([gv_x])
+
+ builder2.start_writing()
+ args_gv = [gv_x]
+ label = builder2.enter_next_block([signed_kind], args_gv)
+ [gv_x2] = args_gv
+
+ gvs = []
+ for i in range(50):
+ gvs.append(builder2.genop2("int_mul", gv_x2, rgenop.genconst(i)))
+
+ gvs.append(builder2.genop_call(sigtoken, gv_verysmall_callable,
+ [gv_x2]))
+
+ while len(gvs) > 1:
+ gvs.append(builder2.genop2("int_add", gvs.pop(), gvs.pop()))
+
+ builder2.finish_and_return(sigtoken, gvs.pop())
+
+ builder.start_writing()
+ builder.finish_and_goto([gv_x], label)
+ builder.end()
+ fnptr = self.cast(gv_callable, 1)
+
+ res = fnptr(1291)
+ assert res == 1291 * (49*50/2) + 17
From arigo at codespeak.net Sat Jan 13 19:16:05 2007
From: arigo at codespeak.net (arigo at codespeak.net)
Date: Sat, 13 Jan 2007 19:16:05 +0100 (CET)
Subject: [pypy-svn] r36694 - pypy/branch/i386-regalloc/pypy/jit/codegen/i386
Message-ID: <20070113181605.8BEA61008F@code0.codespeak.net>
Author: arigo
Date: Sat Jan 13 19:16:04 2007
New Revision: 36694
Modified:
pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
Log:
Fix for test_jump_to_block_with_many_vars.
Modified: pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py
==============================================================================
--- pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py (original)
+++ pypy/branch/i386-regalloc/pypy/jit/codegen/i386/rgenop.py Sat Jan 13 19:16:04 2007
@@ -282,10 +282,12 @@
def generate(self, allocator):
lbl = self.lbl
lbl.targetaddr = allocator.mc.tell()
+ lbl.targetstackdepth = allocator.required_frame_depth
lbl.inputoperands = [allocator.get_operand(v) for v in self.args_gv]
class Label(GenLabel):
targetaddr = 0
+ targetstackdepth = 0
inputoperands = None
class OpCall(Operation):
@@ -687,6 +689,7 @@
if last_n >= 0:
if CALL_ALIGN > 1:
last_n = (last_n & ~(CALL_ALIGN-1)) + (CALL_ALIGN-1)
+ self.required_frame_depth = last_n + 1
self.mc.LEA(esp, stack_op(last_n))
# XXX naive algo for now
for loc, srcoperand in initial_moves:
@@ -731,7 +734,8 @@
def generate_block_code(self, final_vars_gv, force_vars=[],
force_operands=[],
- renaming=True):
+ renaming=True,
+ minimal_stack_depth=0):
allocator = RegAllocator()
allocator.set_final(final_vars_gv)
if not renaming:
@@ -742,6 +746,8 @@
allocator.force_var_operands(self.inputargs_gv, self.inputoperands,
at_start=True)
allocator.allocate_registers()
+ if allocator.required_frame_depth < minimal_stack_depth:
+ allocator.required_frame_depth = minimal_stack_depth
mc = self.start_mc()
allocator.mc = mc
allocator.generate_initial_moves()
@@ -819,7 +825,8 @@
self.start_writing()
operands = targetlbl.inputoperands
assert operands is not None
- mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands)
+ mc = self.generate_block_code(outputargs_gv, outputargs_gv, operands,
+ minimal_stack_depth = targetlbl.targetstackdepth)
mc.JMP(rel32(targetlbl.targetaddr))
self.rgenop.close_mc(mc)
From ericvrp at codespeak.net Sat Jan 13 19:30:55 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 13 Jan 2007 19:30:55 +0100 (CET)
Subject: [pypy-svn] r36695 - pypy/dist/pypy/jit/codegen/test
Message-ID: <20070113183055.5001410074@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 13 19:30:54 2007
New Revision: 36695
Modified:
pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
Log:
added builder.end()
Modified: pypy/dist/pypy/jit/codegen/test/rgenop_tests.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/test/rgenop_tests.py (original)
+++ pypy/dist/pypy/jit/codegen/test/rgenop_tests.py Sat Jan 13 19:30:54 2007
@@ -803,6 +803,7 @@
builder, gv_verysmall_callable, [gv_x] = rgenop.newgraph(sigtoken,
"verysmall")
builder.finish_and_return(sigtoken, rgenop.genconst(17))
+ builder.end()
builder, gv_callable, [gv_x] = rgenop.newgraph(sigtoken,
"jtbwmv")
From santagada at codespeak.net Sat Jan 13 22:16:01 2007
From: santagada at codespeak.net (santagada at codespeak.net)
Date: Sat, 13 Jan 2007 22:16:01 +0100 (CET)
Subject: [pypy-svn] r36700 - in pypy/dist/pypy/lang/js: . test
Message-ID: <20070113211601.828E110086@code0.codespeak.net>
Author: santagada
Date: Sat Jan 13 22:15:59 2007
New Revision: 36700
Modified:
pypy/dist/pypy/lang/js/interpreter.py
pypy/dist/pypy/lang/js/jsobj.py
pypy/dist/pypy/lang/js/test/test_interp.py
Log:
3 tests to being able to run the ecma tests
Modified: pypy/dist/pypy/lang/js/interpreter.py
==============================================================================
--- pypy/dist/pypy/lang/js/interpreter.py (original)
+++ pypy/dist/pypy/lang/js/interpreter.py Sat Jan 13 22:15:59 2007
@@ -64,8 +64,19 @@
temp_tree = parse_bytecode(bytecode)
return from_tree(temp_tree)
-def evaljs(ctx, code):
+def evaljs(ctx, args, this):
+ if len(args) >= 1:
+ code = args[0]
+ else:
+ code = W_String('')
return load_source(code.ToString()).execute(ctx)
+
+def printjs(ctx, args, this):
+ writer(",".join([i.GetValue().ToString() for i in args]))
+ return w_Undefined
+
+def objectconstructor(ctx, args, this):
+ return W_Object()
class Interpreter(object):
"""Creates a js interpreter"""
@@ -82,18 +93,23 @@
w_Function.Put('constructor', w_Function)
#Object stuff
- w_Object = W_Object(Prototype=w_Function)
+ w_Object = W_Builtin(Prototype=w_Function)
+ w_Object.set_builtin_call(objectconstructor)
w_Object.Put('length', W_Number(1), ro=True, dd=True)
w_Object.Put('prototype', w_ObjPrototype, dd=True, de=True, ro=True)
w_ObjPrototype.Put('constructor', w_Object)
#And some other stuff
w_Array = W_Array([])
- w_Global.Put('prototype', W_String('Object'))
w_Global.Put('Object', w_Object)
w_Global.Put('Function', w_Function)
w_Global.Put('Array', w_Array)
- w_Global.Put('eval', W_Builtin(evaljs, context=True, args=1))
+ evalbuiltin = W_Builtin(Class='function')
+ evalbuiltin.set_builtin_call(evaljs)
+ w_Global.Put('eval', evalbuiltin)
+ printbuiltin = W_Builtin(Class='function')
+ printbuiltin.set_builtin_call(printjs)
+ w_Global.Put('print', printbuiltin)
self.global_context = ctx
self.w_Global = w_Global
@@ -173,13 +189,9 @@
def eval(self, ctx):
name = self.identifier.get_literal()
- if name == 'print':
- writer(",".join([i.GetValue().ToString() for i in self.arglist.get_args(ctx)]))
- return w_Null
- else:
- w_obj = ctx.resolve_identifier(name).GetValue()
- retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.get_args(ctx)])
- return retval
+ w_obj = ctx.resolve_identifier(name).GetValue()
+ retval = w_obj.Call(ctx=ctx, args=[i for i in self.arglist.get_args(ctx)])
+ return retval
class Comma(BinaryOp):
@@ -393,11 +405,25 @@
self.newexpr = newexpr
def eval(self, ctx):
+ print self.newexpr
x = self.newexpr.eval(ctx).GetValue()
- if not isinstance(x, W_Object):
+ if not isinstance(x, W_PrimitiveObject):
raise TypeError()
return x.Construct(ctx=ctx)
+
+class NewWithArgs(Expression):
+ def __init__(self, newexpr, arglist):
+ self.newexpr = newexpr
+ self.arglist = arglist
+
+ def eval(self, ctx):
+ print self.newexpr
+ x = self.newexpr.eval(ctx).GetValue()
+ if not isinstance(x, W_PrimitiveObject):
+ raise TypeError()
+
+ return x.Construct(ctx=ctx, args=[i for i in self.arglist.get_args(ctx)])
class Number(Expression):
@@ -694,6 +720,8 @@
node = Ne(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NEW':
node = New(from_tree(gettreeitem(t, '0')))
+ elif tp == 'NEW_WITH_ARGS':
+ node = NewWithArgs(from_tree(gettreeitem(t, '0')), from_tree(gettreeitem(t, '1')))
elif tp == 'NUMBER':
node = Number(float(gettreeitem(t, 'value').additional_info))
elif tp == 'OBJECT_INIT':
Modified: pypy/dist/pypy/lang/js/jsobj.py
==============================================================================
--- pypy/dist/pypy/lang/js/jsobj.py (original)
+++ pypy/dist/pypy/lang/js/jsobj.py Sat Jan 13 22:15:59 2007
@@ -20,7 +20,7 @@
INF = 1e300 * 1e300
MINF = -INF
-NaN = INF/INF
+NaN = INF/INF
class Property(object):
@@ -120,12 +120,10 @@
def ToPrimitive(self, ctx, PreferredType):
return self
-class W_Object(W_Root):
+class W_PrimitiveObject(W_Root):
def __init__(self, ctx=None, Prototype=None, Class='Object',
Value=w_Undefined, callfunc=None):
self.propdict = {}
- self.propdict['toString'] = Property('toString',
- W_Builtin(self.__str__))
self.propdict['prototype'] = Property('prototype', w_Undefined,
dd=True)
self.Prototype = Prototype
@@ -154,16 +152,14 @@
return val
def Construct(self, ctx, args=[]):
- if self.callfunc is None:
- raise TypeError()
obj = W_Object(Class='Object')
prot = self.Get('prototype')
- if isinstance(prot, W_Object):
+ if isinstance(prot, W_PrimitiveObject):
obj.Prototype = prot
else:
obj.Prototype = ctx.get_global().Get('Object')
ret = self.Call(ctx, args, this=obj)
- if isinstance(ret, W_Object):
+ if isinstance(ret, W_PrimitiveObject):
return ret
else:
return obj
@@ -235,28 +231,49 @@
return 'function'
else:
return 'object'
+
+ def str_builtin(self, ctx, args, this):
+ return W_String(self.ToString())
+
+class W_Object(W_PrimitiveObject):
+ def __init__(self, ctx=None, Prototype=None, Class='Object',
+ Value=w_Undefined, callfunc=None):
+ W_PrimitiveObject.__init__(self, ctx, Prototype,
+ Class, Value, callfunc)
+ toString = W_Builtin()
+ toString.set_builtin_call(self.str_builtin)
+ self.propdict['toString'] = Property('toString', toString)
+
+
+class W_Builtin(W_PrimitiveObject):
+ def set_builtin_call(self, callfuncbi):
+ self.callfuncbi = callfuncbi
+ def Call(self, ctx, args=[], this = None):
+ return self.callfuncbi(ctx, args, this)
+
+ def type(self):
+ return 'builtin'
-class W_Arguments(W_Object):
+class W_Arguments(W_PrimitiveObject):
def __init__(self, callee, args):
- W_Object.__init__(self, Class='Arguments')
- del self.propdict["toString"]
+ W_PrimitiveObject.__init__(self, Class='Arguments')
del self.propdict["prototype"]
self.Put('callee', callee)
self.Put('length', W_Number(len(args)))
for i in range(len(args)):
self.Put(str(i), args[i])
-class ActivationObject(W_Object):
+class ActivationObject(W_PrimitiveObject):
"""The object used on function calls to hold arguments and this"""
def __init__(self):
- W_Object.__init__(self, Class='Activation')
- del self.propdict["toString"]
+ W_PrimitiveObject.__init__(self, Class='Activation')
del self.propdict["prototype"]
class W_Array(W_Object):
- def __init__(self, items):
- W_Object.__init__(self)
+ def __init__(self, ctx=None, Prototype=None, Class='Array',
+ Value=w_Undefined, callfunc=None):
+ W_Object.__init__(self, ctx, Prototype, Class, Value, callfunc)
self.Put('length', W_Number(0))
def Put(self, P, V):
@@ -273,6 +290,12 @@
# self.propdict['length'].value = W_Number(x)
self.propdict[P] = Property(P, V)
+ def str_builtin(self, ctx, args, this):
+ return W_String(ToString())
+
+ def ToString(self):
+ return ''
+
class W_Boolean(W_Primitive):
def __init__(self, boolval):
@@ -337,25 +360,6 @@
def type(self):
return 'number'
-class W_Builtin(W_Root):
- def __init__(self, builtinfunction, context=False, args=0):
- #W_Object.__init__(self)
- self.builtinfunction = builtinfunction
- self.context = context
- self.args = args
-
- def Call(self, ctx, args=[], this = None):
- py_args = []
- if self.context == True:
- py_args.append(ctx)
- for i in range(self.args):
- py_args.append(args[i])
- res = self.builtinfunction(*py_args)
- return res
-
- def type(self):
- return 'builtin'
-
class W_List(W_Root):
def __init__(self, list_w):
self.list_w = list_w
Modified: pypy/dist/pypy/lang/js/test/test_interp.py
==============================================================================
--- pypy/dist/pypy/lang/js/test/test_interp.py (original)
+++ pypy/dist/pypy/lang/js/test/test_interp.py Sat Jan 13 22:15:59 2007
@@ -21,9 +21,9 @@
assert Plus(Number(3), Number(4)).eval(ExecutionContext()).floatval == 7
l = []
interpreter.writer = l.append
- Script([Semicolon(Call(Identifier('print', None),
- List([Number(1), Number(2)])))],[],[]).execute(ExecutionContext())
- assert l == ['1,2']
+ # Script([Semicolon(Call(Identifier('print', None),
+ # List([Number(1), Number(2)])))],[],[]).execute(ExecutionContext())
+ # assert l == ['1,2']
def assert_prints(self, code, assval):
l = []
@@ -151,11 +151,10 @@
""", ["test"])
def test_array_initializer(self):
- py.test.skip(" TODO: needed for mozilla test suite")
self.assert_prints("""
x = [];
print(x);
- """, ["[]"])
+ """, [""])
def test_throw(self):
self.assert_prints("throw(3)", ["uncaught exception: 3"])
@@ -313,14 +312,8 @@
print(z);
""", ["3","2"])
- def test_load(self):
- py.test.skip("not ready yet")
- self.assert_prints("""
- load("simple.js")
- """, ["3","2"])
-
def test_arrayobject(self):
- py.test.skip(" TODO: needed for mozilla test suite")
+ py.test.skip('not ready yet')
self.assert_prints("""var x = new Array();
print(x.length);""", ['0'])
@@ -341,10 +334,13 @@
""", W_Boolean(True))
def test_switch(self):
- py.test.skip(" TODO: needed for mozilla test suite")
+ py.test.skip('not ready yet')
def test_newwithargs(self):
- py.test.skip(" TODO: needed for mozilla test suite")
+ self.assert_prints("""
+ var x = new Object(1,2,3,4);
+ print(x)
+ """, ["[object Object]"])
def test_increment(self):
self.assert_prints("""
@@ -379,7 +375,7 @@
print(y)""", ["5"])
def test_smallthings(self):
- py.test.skip(" TODO: needed for mozilla test suite")
+ py.test.skip('not ready yet')
x = """
var x;
if ( gc == undefined ) {
From pedronis at codespeak.net Sat Jan 13 23:12:28 2007
From: pedronis at codespeak.net (pedronis at codespeak.net)
Date: Sat, 13 Jan 2007 23:12:28 +0100 (CET)
Subject: [pypy-svn] r36701 - pypy/dist/pypy/translator/test
Message-ID: <20070113221228.898C410086@code0.codespeak.net>
Author: pedronis
Date: Sat Jan 13 23:12:24 2007
New Revision: 36701
Modified:
pypy/dist/pypy/translator/test/test_driver.py
Log:
now we have jvm backend support in the driver
Modified: pypy/dist/pypy/translator/test/test_driver.py
==============================================================================
--- pypy/dist/pypy/translator/test/test_driver.py (original)
+++ pypy/dist/pypy/translator/test/test_driver.py Sat Jan 13 23:12:24 2007
@@ -42,7 +42,8 @@
'source_squeak', 'source_cli', 'source_c', 'source_llvm',
'compile_cl', 'compile_cli', 'compile_c', 'compile_squeak',
'compile_llvm', 'compile_js', 'run_cl', 'run_squeak',
- 'run_llvm', 'run_c', 'run_js', 'run_cli'])
+ 'run_llvm', 'run_c', 'run_js', 'run_cli',
+ 'compile_jvm', 'source_jvm', 'run_jvm'])
td = TranslationDriver({'backend': None, 'type_system': 'lltype'})
From ericvrp at codespeak.net Sat Jan 13 23:15:06 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sat, 13 Jan 2007 23:15:06 +0100 (CET)
Subject: [pypy-svn] r36702 - pypy/dist/pypy/jit/codegen/llvm
Message-ID: <20070113221506.22F6810086@code0.codespeak.net>
Author: ericvrp
Date: Sat Jan 13 23:15:04 2007
New Revision: 36702
Modified:
pypy/dist/pypy/jit/codegen/llvm/compatibility.py
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
Log:
inttoptr casts support
Modified: pypy/dist/pypy/jit/codegen/llvm/compatibility.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/compatibility.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/compatibility.py Sat Jan 13 23:15:04 2007
@@ -6,7 +6,7 @@
if llvm_version() < 2.0:
icmp = scmp = ucmp = fcmp = 'set'
- inttoptr = trunc = zext = bitcast = 'cast'
+ inttoptr = trunc = zext = bitcast = inttoptr = 'cast'
shr_prefix = ['', '']
i8 = 'ubyte'
i16 = 'short'
@@ -22,6 +22,7 @@
trunc = 'trunc'
zext = 'zext'
bitcast = 'bitcast'
+ inttoptr = 'inttoptr'
shr_prefix = ['l', 'a']
define = 'define'
i8 = 'i8'
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Sat Jan 13 23:15:04 2007
@@ -9,7 +9,7 @@
from pypy.jit.codegen.i386.rgenop import gc_malloc_fnaddr
from pypy.jit.codegen.llvm.conftest import option
from pypy.jit.codegen.llvm.compatibility import icmp, scmp, ucmp, fcmp, inttoptr,\
- trunc, zext, bitcast, shr_prefix, define, i1, i8, i16, i32, f64
+ trunc, zext, bitcast, inttoptr, shr_prefix, define, i1, i8, i16, i32, f64
pi8 = i8 + '*'
@@ -902,7 +902,7 @@
if isinstance(gv_fnptr, AddrConst):
gv_fn = Var(self._funcsig_type(args_gv, restype) + '*')
self.asm.append(' %s=%s %s %s to %s' % (
- gv_fn.operand2(), bitcast, i32, gv_fnptr.operand2(), gv_fn.type))
+ gv_fn.operand2(), inttoptr, i32, gv_fnptr.operand2(), gv_fn.type))
funcsig = gv_fn.operand()
else:
#XXX we probably need to call an address directly if we can't resolve the funcsig
From ericvrp at codespeak.net Sun Jan 14 00:12:53 2007
From: ericvrp at codespeak.net (ericvrp at codespeak.net)
Date: Sun, 14 Jan 2007 00:12:53 +0100 (CET)
Subject: [pypy-svn] r36704 - in pypy/dist/pypy/jit/codegen/llvm: . test
Message-ID: <20070113231253.C993E10086@code0.codespeak.net>
Author: ericvrp
Date: Sun Jan 14 00:12:43 2007
New Revision: 36704
Modified:
pypy/dist/pypy/jit/codegen/llvm/rgenop.py
pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py
Log:
jit/codegen/llvm, more pushing and pulling of the pointer casts.
This will soon need refactoring!
Modified: pypy/dist/pypy/jit/codegen/llvm/rgenop.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/rgenop.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/rgenop.py Sun Jan 14 00:12:43 2007
@@ -557,26 +557,38 @@
#XXX 'cast' has been replaced by many sext/zext/uitofp/... opcodes in the upcoming llvm 2.0.
#The lines upto /XXX should be refactored to do the right thing
- def genop_same_as(self, kind, gv_x):
+ def genop_same_as(self, kind, gv_x): #XXX why do we need a 'kind' here?
if gv_x.is_const: # must always return a var
- gv_result = Var(gv_x.type)
- self.asm.append(' %s=%s %s to %s' % (
- gv_result.operand2(), bitcast, gv_x.operand(), gv_x.type))
+ restype = gv_x.type
+ gv_result = Var(restype)
+ if restype[-1] == '*':
+ cst = inttoptr
+ t = i32
+ else:
+ cst = bitcast
+ t = restype
+ self.asm.append(' %s=%s %s %s to %s ;1' % (
+ gv_result.operand2(), cst, t, gv_x.operand2(), restype))
return gv_result
else:
return gv_x
def _cast_to(self, gv_x, restype=None):
- restype = restype or gv_x.type
- if restype is gv_x.type:
+ t = gv_x.type
+ restype = restype or t
+ if restype is t:
return self.genop_same_as(None, gv_x)
gv_result = Var(restype)
if restype[-1] == '*':
- t = bitcast
- else:
- t = zext
- self.asm.append(' %s=%s %s to %s' % (
- gv_result.operand2(), t, gv_x.operand(), restype))
+ if gv_x.is_const:
+ cst = inttoptr
+ t = i32
+ else:
+ cst = bitcast
+ else:
+ cst = zext
+ self.asm.append(' %s=%s %s %s to %s ;2' % (
+ gv_result.operand2(), cst, t, gv_x.operand2(), restype))
return gv_result
def _trunc_to(self, gv_x, restype=None):
@@ -907,11 +919,19 @@
else:
#XXX we probably need to call an address directly if we can't resolve the funcsig
funcsig = self.rgenop.funcsig[gv_fnptr.get_integer_value()]
+ args_gv2 = []
+ for v in args_gv:
+ if v.is_const and v.type[-1] == '*': #or use some kind of 'inline' cast (see LangRef)
+ t = Var(v.type)
+ self.asm.append(' %s=%s %s %s to %s' % (
+ t.operand2(), inttoptr, i32, v.operand2(), v.type))
+ v = t
+ args_gv2.append(v)
gv_returnvar = Var(restype)
self.asm.append(' %s=call %s(%s)' % (
gv_returnvar.operand2(),
funcsig,
- ','.join([v.operand() for v in args_gv])))
+ ','.join([v.operand() for v in args_gv2])))
return gv_returnvar
def finish_and_return(self, sigtoken, gv_returnvar):
Modified: pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py
==============================================================================
--- pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py (original)
+++ pypy/dist/pypy/jit/codegen/llvm/test/test_genc_vlist.py Sun Jan 14 00:12:43 2007
@@ -8,8 +8,3 @@
# for the individual tests see
# ====> ../../../timeshifter/test/test_vlist.py
-
- def skip(self):
- py.test.skip("WIP")
-
- test_force = skip
From fijal at codespeak.net Sun Jan 14 00:23:26 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 14 Jan 2007 00:23:26 +0100 (CET)
Subject: [pypy-svn] r36705 - pypy/dist/pypy/annotation
Message-ID: <20070113232326.C67FD10086@code0.codespeak.net>
Author: fijal
Date: Sun Jan 14 00:23:25 2007
New Revision: 36705
Modified:
pypy/dist/pypy/annotation/signature.py
Log:
Make the tests pass
Modified: pypy/dist/pypy/annotation/signature.py
==============================================================================
--- pypy/dist/pypy/annotation/signature.py (original)
+++ pypy/dist/pypy/annotation/signature.py Sun Jan 14 00:23:25 2007
@@ -39,13 +39,11 @@
annotation(t.values()[0])))
elif type(t) is types.NoneType:
return s_None
- assert isinstance(t, (type, types.ClassType))
- if t is bool:
+ #assert isinstance(t, (type, types.ClassType))
+ elif t is bool:
return SomeBool()
elif t is int:
return SomeInteger()
- elif issubclass(t, str): # py.lib uses annotated str subclasses
- return SomeString()
elif t is float:
return SomeFloat()
elif t is list:
@@ -63,6 +61,12 @@
elif bookkeeper and t.__module__ != '__builtin__' and t not in bookkeeper.pbctypes:
classdef = bookkeeper.getuniqueclassdef(t)
return SomeInstance(classdef)
+ elif extregistry.is_registered(t):
+ entry = extregistry.lookup(t)
+ entry.bookkeeper = bookkeeper
+ return entry.compute_result_annotation()
+ elif issubclass(t, str): # py.lib uses annotated str subclasses
+ return SomeString()
else:
o = SomeObject()
if t != object:
From fijal at codespeak.net Sun Jan 14 00:23:43 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 14 Jan 2007 00:23:43 +0100 (CET)
Subject: [pypy-svn] r36706 - pypy/dist/pypy/annotation
Message-ID: <20070113232343.8AA221008A@code0.codespeak.net>
Author: fijal
Date: Sun Jan 14 00:23:42 2007
New Revision: 36706
Modified:
pypy/dist/pypy/annotation/unaryop.py
Log:
Kill unnecessary code
Modified: pypy/dist/pypy/annotation/unaryop.py
==============================================================================
--- pypy/dist/pypy/annotation/unaryop.py (original)
+++ pypy/dist/pypy/annotation/unaryop.py Sun Jan 14 00:23:42 2007
@@ -14,6 +14,7 @@
from pypy.annotation import builtin
from pypy.annotation.binaryop import _clone ## XXX where to put this?
from pypy.rpython import extregistry
+from pypy.annotation.signature import annotation
# convenience only!
def immutablevalue(x):
@@ -672,15 +673,7 @@
assert s_attr.is_constant()
attr = s_attr.const
entry = extregistry.lookup_type(p.knowntype._class_)
- # we need to flow it, if it's something which can be called
- if isinstance(s_value, SomePBC):
- # we have to have such a declaration to know what we're flowing it with
- bookkeeper = getbookkeeper()
- args_ann = entry.get_arg_annotation(p.knowntype, attr)
- bookkeeper.pbc_call(s_value, bookkeeper.build_args("simple_call", args_ann))
- p.knowntype.check_update()
- if not p.knowntype._fields.has_key(attr):
- entry.set_field_annotation(p.knowntype, attr, s_value)
+ entry.set_field_annotation(p.knowntype, attr, s_value)
def find_method(obj, name):
return obj.knowntype.get_field(name)
From fijal at codespeak.net Sun Jan 14 00:24:47 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 14 Jan 2007 00:24:47 +0100 (CET)
Subject: [pypy-svn] r36707 - pypy/dist/pypy/rpython
Message-ID: <20070113232447.DC11C10089@code0.codespeak.net>
Author: fijal
Date: Sun Jan 14 00:24:46 2007
New Revision: 36707
Modified:
pypy/dist/pypy/rpython/extfunc.py
Log:
Add a convinient annotation, which will later be annotated properly (when having bookkeeper)
Modified: pypy/dist/pypy/rpython/extfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/extfunc.py (original)
+++ pypy/dist/pypy/rpython/extfunc.py Sun Jan 14 00:24:46 2007
@@ -4,6 +4,24 @@
from pypy.objspace.flow.model import Constant
from pypy.annotation.model import unionof
from pypy.annotation.signature import annotation
+from pypy.annotation import model as annmodel
+
+class _callable(object):
+ """ A way to specify the callable annotation, but deferred until
+ we have bookkeeper
+ """
+ def __init__(self, args, result=None):
+ self.args = args
+ self.result = result
+
+class _ext_callable(ExtRegistryEntry):
+ _type_ = _callable
+ # we defer a bit annotation here
+
+ def compute_result_annotation(self):
+ return annmodel.SomeGenericCallable([annotation(i, self.bookkeeper)
+ for i in self.instance.args],
+ annotation(self.instance.result, self.bookkeeper))
class ExtFuncEntry(ExtRegistryEntry):
def compute_result_annotation(self, *args_s):
From fijal at codespeak.net Sun Jan 14 00:27:15 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 14 Jan 2007 00:27:15 +0100 (CET)
Subject: [pypy-svn] r36708 - in pypy/dist/pypy/rpython: . ootypesystem
ootypesystem/test
Message-ID: <20070113232715.1973E10091@code0.codespeak.net>
Author: fijal
Date: Sun Jan 14 00:27:12 2007
New Revision: 36708
Modified:
pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
pypy/dist/pypy/rpython/rexternalobj.py
Log:
Make bltregistry adhere to new style of defining types. Needs a bit of wacking,
but still better than it was before. Added additional checks, which exposed
bunch of bugs here and there.
Modified: pypy/dist/pypy/rpython/ootypesystem/bltregistry.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/bltregistry.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/bltregistry.py Sun Jan 14 00:27:12 2007
@@ -11,6 +11,7 @@
from pypy.rpython.extregistry import ExtRegistryEntry
from pypy.rpython.ootypesystem.extdesc import MethodDesc, ArgDesc
from pypy.annotation.signature import annotation
+from pypy.annotation.model import unionof
class CallableEntry(ExtRegistryEntry):
_type_ = MethodDesc
@@ -94,10 +95,11 @@
self.value = value
def __call__(self, *args):
- #for i in args:
- # if isinstance(i, annmodel.SomePBC):
- # bookkeeper = getbookkeeper()
- # bookkeeper.pbc_call(i, bookkeeper.build_args("simple_call", (self.s_retval,)))
+ args = args[1:]
+ assert len(self.s_args) == len(args)
+ for arg, expected in zip(args, self.s_args):
+ res = unionof(arg, expected)
+ assert expected.contains(res)
return self.s_retval
class ExternalType(ootype.OOType):
@@ -136,13 +138,15 @@
self._methods = frozendict(_signs)
def __hash__(self):
- # FIXME: for now
return hash(self._name)
def set_field(self, attr, knowntype):
self.check_update()
- self._fields[attr] = knowntype
-
+ assert attr in self._fields
+ field_ann = self._fields[attr]
+ res = unionof(knowntype, field_ann)
+ assert res.contains(knowntype)
+
def check_update(self):
if not self.updated:
_fields, _methods = self._data
@@ -155,7 +159,7 @@
def get_field(self, attr):
self.check_update()
return self._fields[attr]
-
+
def find_method(self, meth):
raise NotImplementedError()
@@ -181,8 +185,11 @@
def get_field_annotation(self, ext_obj, attr):
return ext_obj.get_field(attr)
- def get_arg_annotation(self, ext_obj, attr):
- return ext_obj._class_._fields[attr].args_s
+ #def get_arg_annotation(self, ext_obj, attr, s_pbc):
+ # s_field = ext_obj.get_field(attr)
+ # res = unionof(s_field, s_pbc)
+ # assert s_field.contains(res)
+ # return s_field.args_s
def set_field_annotation(self, ext_obj, attr, s_val):
ext_obj.set_field(attr, s_val)
Modified: pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py
==============================================================================
--- pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py (original)
+++ pypy/dist/pypy/rpython/ootypesystem/test/test_bltann.py Sun Jan 14 00:27:12 2007
@@ -127,7 +127,7 @@
def test_callback_field():
def callback(x):
- return 8.3
+ return 8.3 + x
def callback_field():
a = CD()
@@ -137,3 +137,4 @@
a = RPythonAnnotator()
s = a.build_types(callback_field, [])
assert isinstance(s, annmodel.SomeGenericCallable)
+ assert aa.translator._graphof(callback)
Modified: pypy/dist/pypy/rpython/rexternalobj.py
==============================================================================
--- pypy/dist/pypy/rpython/rexternalobj.py (original)
+++ pypy/dist/pypy/rpython/rexternalobj.py Sun Jan 14 00:27:12 2007
@@ -1,13 +1,13 @@
from pypy.annotation import model as annmodel
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.ootypesystem import ootype
-from pypy.rpython.rmodel import Repr
+from pypy.rpython.rmodel import Repr, HalfConcreteWrapper
from pypy.rpython.extfunctable import typetable
from pypy.rpython import rbuiltin
from pypy.rpython.module.support import init_opaque_object
from pypy.objspace.flow.model import Constant
from pypy.rpython import extregistry
-
+from pypy.annotation.signature import annotation
class __extend__(annmodel.SomeExternalObject):
@@ -51,10 +51,17 @@
def rtype_setattr(self, hop):
if self.lowleveltype is ootype.Void:
return
- attr = hop.args_s[1].const
- #self.lowleveltype._check_field(attr)
- vlist = hop.inputargs(self, ootype.Void, hop.args_r[2])
- s_attr = hop.args_s[1]
+ vlist = [hop.inputarg(self, arg=0), hop.inputarg(ootype.Void, arg=1)]
+ field_name = hop.args_s[1].const
+ obj = self.knowntype._class_._fields[field_name]
+ bookkeeper = hop.rtyper.annotator.bookkeeper
+ # XXX WARNING XXX
+ # annotation() here should not be called, but we somehow
+ # have overwritten _fields. This will do no harm, but may hide some
+ # errors
+ r = hop.rtyper.getrepr(annotation(obj, bookkeeper))
+ v = hop.inputarg(r, arg=2)
+ vlist.append(v)
return hop.genop('oosetfield', vlist)
def call_method(self, name, hop):
From fijal at codespeak.net Sun Jan 14 00:29:13 2007
From: fijal at codespeak.net (fijal at codespeak.net)
Date: Sun, 14 Jan 2007 00:29:13 +0100 (CET)
Subject: [pypy-svn] r36709 - in pypy/dist/pypy/translator/js: . demo/jsdemo
modules modules/test test
Message-ID: <20070113232913.730B210093@code0.codespeak.net>
Author: fijal
Date: Sun Jan 14 00:29:09 2007
New Revision: 36709
Modified:
pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
pypy/dist/pypy/translator/js/demo/jsdemo/example.py
pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
pypy/dist/pypy/translator/js/demo/jsdemo/support.py
pypy/dist/pypy/translator/js/jts.py
pypy/dist/pypy/translator/js/modules/dom.py
pypy/dist/pypy/translator/js/modules/test/test_dom.py
pypy/dist/pypy/translator/js/support.py
pypy/dist/pypy/translator/js/test/test_bltn.py
pypy/dist/pypy/translator/js/test/test_main.py
Log:
Rewrite to a new version of bltregistry. It exposed huge amount of bugs, which
seems to be never tested before :-(
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/bnb.py Sun Jan 14 00:29:09 2007
@@ -11,8 +11,7 @@
PMSG_INLINE_FRAME, PMSG_DEF_ICON
from pypy.translator.js.demo.jsdemo.msgstruct import *
from cherrypy import session
-from pypy.annotation import model as annmodel
-from pypy.annotation.signature import annotation
+from pypy.rpython.extfunc import _callable
import re, time, sys, os, urllib, socket, copy, md5, random
@@ -69,7 +68,7 @@
self.seen = set()
return to_ret
-lambda_None = annmodel.SomeGenericCallable([], result=annotation(None))
+lambda_None = _callable([])
# Needed double inheritance for both server job
# and semi-transparent communication proxy
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/example.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/example.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/example.py Sun Jan 14 00:29:09 2007
@@ -11,6 +11,7 @@
from pypy.translator.js import commproxy
from pypy.annotation import model as annmodel
from pypy.annotation.signature import annotation
+from pypy.rpython.extfunc import _callable
commproxy.USE_MOCHIKIT = False
@@ -39,12 +40,10 @@
def runjs():
httpd.some_callback(callback)
-lambda_None = annmodel.SomeGenericCallable([], result=annotation(None))
-
class Server(HTTPServer, BasicExternal):
# Methods and signatures how they are rendered for JS
_methods = {
- 'some_callback' : MethodDesc([('callback', lambda_None)], {str:str})
+ 'some_callback' : MethodDesc([('callback', _callable([{str:str}]))], {str:str})
}
_render_xmlhttp = True
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/pythonconsole.py Sun Jan 14 00:29:09 2007
@@ -16,10 +16,7 @@
from pypy.rpython.ootypesystem.bltregistry import MethodDesc, BasicExternal
from pypy.translator.js import commproxy
from pypy.translator.js.modules.mochikit import escapeHTML
-from pypy.annotation import model as annmodel
-from pypy.annotation.signature import annotation
-
-lambda_None = annmodel.SomeGenericCallable([], result=annotation(None))
+from pypy.rpython.extfunc import _callable
from pypy.translator.js.demo.jsdemo import support
@@ -96,7 +93,7 @@
# Methods and signatures how they are rendered for JS
_methods = {
'some_callback' : MethodDesc([('cmd', str),
- ('callback', lambda_None)],
+ ('callback', _callable([{str:str}]))],
{str:str})
}
Modified: pypy/dist/pypy/translator/js/demo/jsdemo/support.py
==============================================================================
--- pypy/dist/pypy/translator/js/demo/jsdemo/support.py (original)
+++ pypy/dist/pypy/translator/js/demo/jsdemo/support.py Sun Jan 14 00:29:09 2007
@@ -2,7 +2,7 @@
import sys, new
from pypy.translator.js.main import rpython2javascript
-def js_source(functions, use_pdb=False):
+def js_source(functions, use_pdb=True):
mod = new.module('_js_src')
function_names = []
for func in functions:
Modified: pypy/dist/pypy/translator/js/jts.py
==============================================================================
--- pypy/dist/pypy/translator/js/jts.py (original)
+++ pypy/dist/pypy/translator/js/jts.py Sun Jan 14 00:29:09 2007
@@ -86,11 +86,6 @@
else:
val = 'true'
elif _type is Void:
- #if isinstance(v, FunctionType):
- # graph = self.db.translator.annotator.bookkeeper.getdesc(v).cachedgraph(None)
- # self.db.pending_function(graph)
- # val = graph.name
- #else:
val = 'undefined'
elif isinstance(_type,String.__class__):
val = '%r'%v._str
Modified: pypy/dist/pypy/translator/js/modules/dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/dom.py Sun Jan 14 00:29:09 2007
@@ -26,7 +26,7 @@
from pypy.annotation.signature import annotation
from pypy.annotation import model as annmodel
-from pypy.translator.js.support import _callable
+from pypy.rpython.extfunc import _callable
# EventTarget is the base class for Nodes and Window
class EventTarget(BasicExternal):
@@ -344,9 +344,9 @@
lambda_returning_true = _callable([Event])
EventTarget._methods = {
- 'addEventListener' : MethodDesc([str, lambda_returning_true]),
+ 'addEventListener' : MethodDesc([str, lambda_returning_true, bool]),
'dispatchEvent' : MethodDesc([str], bool),
- 'removeEventListener' : MethodDesc([str, lambda_returning_true]),
+ 'removeEventListener' : MethodDesc([str, lambda_returning_true, bool]),
}
Node._fields = EventTarget._fields.copy()
@@ -402,6 +402,7 @@
'scrollLeft' : int,
'scrollTop' : int,
'scrollWidth' : int,
+ 'disabled': bool,
# HTML specific
'style' : Style,
'tabIndex' : int,
Modified: pypy/dist/pypy/translator/js/modules/test/test_dom.py
==============================================================================
--- pypy/dist/pypy/translator/js/modules/test/test_dom.py (original)
+++ pypy/dist/pypy/translator/js/modules/test/test_dom.py Sun Jan 14 00:29:09 2007
@@ -1,3 +1,5 @@
+
+# -*- encoding: utf-8 -*-
import py
from pypy.translator.js.modules import dom
from pypy.translator.js.main import rpython2javascript
@@ -364,13 +366,13 @@
'color: green;">