[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