[pypy-svn] r49254 - in pypy/dist/pypy/translator: jvm jvm/src/pypy oosupport/test_template
niko at codespeak.net
niko at codespeak.net
Sat Dec 1 18:59:01 CET 2007
Author: niko
Date: Sat Dec 1 18:59:01 2007
New Revision: 49254
Modified:
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
pypy/dist/pypy/translator/oosupport/test_template/builtin.py
Log:
fix math.modf in the jvm:
1. the code in PyPy.java was slightly wrong
2. the static signature cannot reference generated objects,
so when they are returned we must use jObject instead and insert
a downcast
3. add a test to oosupport/builtin for modf
Modified: pypy/dist/pypy/translator/jvm/generator.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/generator.py (original)
+++ pypy/dist/pypy/translator/jvm/generator.py Sat Dec 1 18:59:01 2007
@@ -1047,15 +1047,32 @@
def call_primitive(self, op, module, name):
callee = op.args[0].value
- argtypes, rettype = self.db.types_for_signature(
+ jargtypes, jrettype = self.db.types_for_signature(
callee._TYPE.ARGS, callee._TYPE.RESULT)
+
+ # Determine what class the primitive is implemented in:
if module == 'll_os':
jcls = jll_os
else:
jcls = jPyPy
- mthd = Method.v(jcls, name, argtypes, rettype)
+
+ # Determine the method signature:
+ # n.b.: if the method returns a generated type, then
+ # it's static type will be Object. This is because
+ # the method cannot directly refer to the Java type in
+ # .java source, as its name is not yet known.
+ if jrettype.is_generated():
+ mthd = Method.v(jcls, name, jargtypes, jObject)
+ else:
+ mthd = Method.v(jcls, name, jargtypes, jrettype)
+
+ # Invoke the method
self.emit(mthd)
+ # Cast the result, if needed
+ if jrettype.is_generated():
+ self.downcast_jtype(jrettype)
+
def prepare_call_oostring(self, OOTYPE):
# Load the PyPy object pointer onto the stack:
self.push_pypy()
Modified: pypy/dist/pypy/translator/jvm/node.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/node.py (original)
+++ pypy/dist/pypy/translator/jvm/node.py Sat Dec 1 18:59:01 2007
@@ -20,9 +20,9 @@
from pypy.rpython.ootypesystem import \
ootype, rclass
from pypy.translator.jvm.typesystem import \
- JvmClassType, jString, jStringArray, jVoid, jThrowable, jInt, \
+ JvmGeneratedClassType, jString, jStringArray, jVoid, jThrowable, jInt, \
jObject, JvmType, jStringBuilder, jPyPyInterlink, jCallbackInterfaces, \
- JvmInterfaceType, jPyPy
+ JvmGeneratedInterfaceType, jPyPy
from pypy.translator.jvm.opcodes import \
opcodes
from pypy.translator.jvm.option import \
@@ -445,7 +445,7 @@
OOFunction._render_op(self, op)
-class StaticMethodInterface(Node, JvmClassType):
+class StaticMethodInterface(Node, JvmGeneratedClassType):
"""
We generate an abstract base class when we need function pointers,
which correspond to constants of StaticMethod ootype. We need a
@@ -467,7 +467,7 @@
argtypes: list of JvmTypes
rettype: JvmType
"""
- JvmClassType.__init__(self, name)
+ JvmGeneratedClassType.__init__(self, name)
assert isinstance(jrettype, JvmType)
self.java_argument_types = [self] + list(jargtypes)
self.java_return_type = jrettype
@@ -539,7 +539,7 @@
gen.end_class()
-class StaticMethodImplementation(Node, JvmClassType):
+class StaticMethodImplementation(Node, JvmGeneratedClassType):
"""
In addition to the StaticMethodInterface, we must generate an
implementation for each specific method that is called. These
@@ -567,7 +567,7 @@
}
"""
def __init__(self, name, super_class, bound_to_jty, impl_method):
- JvmClassType.__init__(self, name)
+ JvmGeneratedClassType.__init__(self, name)
self.super_class = super_class
self.impl_method = impl_method
self.dump_method = ConstantStringDumpMethod(
@@ -633,13 +633,13 @@
gen.end_function()
gen.end_class()
-class Interface(Node, JvmInterfaceType):
+class Interface(Node, JvmGeneratedInterfaceType):
"""
Represents an interface to be generated. The only class that we
currently generate into an interface is ootype.ROOT.
"""
def __init__(self, name):
- JvmClassType.__init__(self, name)
+ JvmGeneratedInterfaceType.__init__(self, name)
self.super_class = jObject
self.rendered = False
self.properties = {}
@@ -675,7 +675,7 @@
gen.end_class()
-class Class(Node, JvmClassType):
+class Class(Node, JvmGeneratedClassType):
""" Represents a class to be emitted. Note that currently, classes
are emitted all in one shot, not piecemeal. """
@@ -685,7 +685,7 @@
'name' should be a fully qualified Java class name like
"java.lang.String", supercls is a Class object
"""
- JvmClassType.__init__(self, name)
+ JvmGeneratedClassType.__init__(self, name)
self.rendered = False # has rendering occurred?
self.abstract = False # is this an abstract class?
self.fields = {} # maps field name to jvmgen.Field object
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 Sat Dec 1 18:59:01 2007
@@ -988,13 +988,8 @@
}
public Object ll_math_modf(double x) {
- if (x >= 0) {
- double floor_x = Math.floor(x);
- return interlink.recordFloatFloat(floor_x, x - floor_x);
- }
-
- double ceil_x = Math.ceil(x);
- return interlink.recordFloatFloat(ceil_x, x + ceil_x);
+ double integer_x = (x >= 0 ? Math.floor(x) : Math.ceil(x));
+ return interlink.recordFloatFloat(x - integer_x, integer_x);
}
public double ll_math_exp(double x) {
Modified: pypy/dist/pypy/translator/jvm/typesystem.py
==============================================================================
--- pypy/dist/pypy/translator/jvm/typesystem.py (original)
+++ pypy/dist/pypy/translator/jvm/typesystem.py Sat Dec 1 18:59:01 2007
@@ -127,6 +127,11 @@
exist on this type. """
raise NotImplementedException
+ def is_generated(self):
+ """ Indicates whether the source for this type is generated by
+ pypy. """
+ return False
+
def __repr__(self):
return "%s<%s>" % (self.__class__.__name__, self.descriptor)
@@ -146,9 +151,21 @@
def lookup_method(self, methodnm):
raise KeyError(fieldnm) # we treat as opaque type
+class JvmGeneratedClassType(JvmClassType):
+ """ Abstract class extended by the classes in node.py that represent
+ generated classes """
+ def is_generated(self):
+ return True
+
class JvmInterfaceType(JvmClassType):
pass
+class JvmGeneratedInterfaceType(JvmInterfaceType):
+ """ Abstract class extended by the classes in node.py that represent
+ generated interfaces """
+ def is_generated(self):
+ return True
+
jIntegerClass = JvmClassType('java.lang.Integer')
jLongClass = JvmClassType('java.lang.Long')
jDoubleClass = JvmClassType('java.lang.Double')
Modified: pypy/dist/pypy/translator/oosupport/test_template/builtin.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/test_template/builtin.py (original)
+++ pypy/dist/pypy/translator/oosupport/test_template/builtin.py Sat Dec 1 18:59:01 2007
@@ -1,4 +1,4 @@
-import os
+import os, math
import errno
import stat
from py.builtin import sorted
@@ -138,6 +138,16 @@
# XXX: remember to test ll_os_readlink and ll_os_pipe as soon as
# they are implemented
+ def test_math_modf(self):
+ def fn(x):
+ return math.modf(x)
+ for x in (.5, 1, 1.5):
+ for y in (1, -1):
+ act_res = self.interpret(fn, [x*y])
+ exp_res = math.modf(x*y)
+ assert act_res.item0 == exp_res[0]
+ assert act_res.item1 == exp_res[1]
+
class BaseTestTime(llBaseTestTime):
More information about the pypy-svn
mailing list