Hi Paul, I'm cc-ing pypy-dev. Really, don't be shy and don't worry to bother the list with your questions. They are not spam. I'm sure that the others are happy to hear your questions and also to answer in case I can't do it immediately (as happened in the last weekend). Paul deGrandis wrote:
Antonio,
I've been working on the JVM backend. When I trace the float tests that look at uint handling, weird NEGATIVE values pop up. I originally associated these with overflow, but it's a different issue. Any insight? The way to do unsigned values in Java is to use the next primary type larger, for example, a uint is stored in a double... but currently no checks exist for negative values.
as Niko pointed out unsigned types are stored in the corresponding signed types in the JVM: this is ok becasue they occupy the same amount of bits, but you have to been careful when dealing with them because the JVM thinks you want to represent a signed value. In particular, if you try to print one to stdout it will be printed as a signed, and so this might be the reason why you see negative values. You have to write a custom procedure to format unsigned values into the right human readable implementation. Please note that this is necessary only during testing or when doing I/O: as long as your unsigned values are kept inside the JVM, they works just fine (apart from comparisons). The simplest way I can think to format an unsigned into an human readable form is to convert it into a double, as I already wrote in a previous email: double from_uint(int x) { double res = x; if (x < 0) // i.e., the leftmost but is 1 res += 4294967294; return res; } But again, you should use this *only* for I/O and testing, not for doing any real operation.
I looked at the test_overflow but these tests don't make sense for the jvm. You have overflow built in to CLI so you want to make sure that ovf_check from the rpython definition works, but the JVM defines these operations. What exactly are these tests aiming to illustrate and test?
RPython is a language with a (more or less :-)) well defined semantics, so every backend must take care of implementing this semantics correctly, even if it's not natively supported by the underlying platform. In this particular case, RPython programs expect overflow to be detected correctly. If the JVM does not do this for you, you have to handle those cases by yourself. GenC has the same problem: the C platform does not detect any overflow, so it must explicitly check for that; you can easily reuse the same logic; for example, this macro is taken from translator/c/src/int.h: #define OP_INT_ADD_OVF(x,y,r) \ OP_INT_ADD(x,y,r); \ if ((r^(x)) >= 0 || (r^(y)) >= 0); \ else FAIL_OVF("integer addition") for genjvm, you could e.g. write a java function doing the same (and raising the appropriate exception in case of overflow).
I haven't tackled overriding default values (as skipped in test_class) yet, but that's really all there is needed left to pass the test_class requirements
I think you could skip this for now. IIRC it's only needed to translate pypy with the thunk objspace, it's not a priority.
I'm still working on the others, but I don't think I'll have trouble having these first bugs fixed by the end of the work day on the 27th.
ok, that's cool! :-)
Lastly, what is the easy approach to I/O and external functions?
the easy approach is to forward the external functions to the backend, which will take care of rendering them as appropriate (usually by calling an helper function written in java). This approach is already used to implement time.time, time.clock and os.write: you can find their implementation in jvm/src/pypy/PyPy.java (ll_time_time, ll_time_clock, ll_os_write). The code that calls these functions is in jvm/generator.py, method 'call_primitive'. ciao Anto
Lastly, what is the easy approach to I/O and external functions?
the easy approach is to forward the external functions to the backend, which will take care of rendering them as appropriate (usually by calling an helper function written in java). This approach is already used to implement time.time, time.clock and os.write: you can find their implementation in jvm/src/pypy/PyPy.java (ll_time_time, ll_time_clock, ll_os_write). The code that calls these functions is in jvm/generator.py, method 'call_primitive'.
ciao Anto
Small addition from my side. I've been playing recently with a very naive reuse of BasicExternal infrastructure which is supporting external objects in JS backend. Looks nice so far and I'm able to hard code some RPython-accessible objects (in a very ad hoc manner, mind you). I don't know Java that well, but I would be happy to help with this issue. Cheers, fijal :.
participants (2)
-
Antonio Cuni
-
Maciek Fijalkowski