oracle / graalpython

GraalPy – A high-performance embeddable Python 3 runtime for Java
https://www.graalvm.org/python/
Other
1.26k stars 112 forks source link

[Interop] Problems with large integers #60

Open fniephaus opened 5 years ago

fniephaus commented 5 years ago

It looks like there are different interop problems when working with large integers (larger than long, so probably BigInteger-related):

GraalVM MultiLanguage Shell 1.0.0-rc12
Copyright (c) 2013-2019, Oracle and/or its affiliates
  JavaScript version 1.0
  Python version 3.7.0
  R version 3.5.1
  Ruby version 2.4.4
js> python>
python> import polyglot
python> polyglot.eval(language="js", string="(x) => x * 2")(1234567890)
2469135780.0
python> polyglot.eval(language="js", string="(x) => x * 2")(12345678901234567890)
nan
python> polyglot.eval(language="ruby", string="lambda { | x | return x * 2 }")(1234567890)
2469135780
python> polyglot.eval(language="ruby", string="lambda { | x | return x * 2 }")(12345678901234567890)
Internal error occured: org.graalvm.polyglot.PolyglotException: org.truffleruby.language.control.RaiseException: AttributeError: 'int' object has no attribute '*' (PException)
Translated to internal error (RuntimeError)
Run with --verbose to see the full stack trace.

I don't know know yet whether this is only a GraalPython problem, or whether GraalJS or TruffleRuby also need to be fixed.

timfel commented 5 years ago

Both of these issues are impossible for us to fix, I think. What happens is this: there's a PInt object that wraps a BigInteger. When JS sees this in a binary expression, it'll ask if it can UNBOX it, but cannot (because we'll deny that for BigInteger). So it'll effectively do {} * 2 => NaN. When Ruby fails to unbox, it tries to call the * method, which of course doesn't exist and thus we raise the Python error.

@chumer unless I'm mistaken, there's nothing we can do here, right?

fniephaus commented 5 years ago

Maybe this is a sign that Truffle needs a dedicated class for representing large integers consistently across all language implementations? I understand BigInteger is comparatively old and incompatible with PE anyway. I'm wondering what @chumer thinks about that.

timfel commented 5 years ago

Yes, we can fix the problem for large integers. We'll also have to fix it for Strings. But there's always limits to what you can do. What about e.g. iterators, generators/coroutines? There's always going to be conceptional "types" that you would think should work together but won't.

fniephaus commented 5 years ago

That's right, at some point the framework has to make trade-offs. But maybe large integers and strings are something that should still be supported. As you know, RPython has rbigint for example, too.

smarr commented 5 years ago

Sounds to me as if interop is slowly becoming its own language.

timfel commented 5 years ago

Yes, I'm just saying that what we're missing in general is a definition of the "common language" that everything maps to. It is only implicit through the primitive types and some extra things we support such as message sending

timfel commented 5 years ago

@smarr Of course, it's always been that. It's just not called that, but what else would you be mapping to?

smarr commented 5 years ago

@timfel this wasn't the original vision as I understand it from @grimmerm's work. Originally, it was quite minimal in scope, a behavioral interface. It was not a full featured language.

I am not saying this is a bad thing, but this sounds to me like something that has a quite different scope and implications.

timfel commented 5 years ago

I would argue it's a language as soon as you decide that there's message sending semantics and objects with keys. Leave alone the additional stuff that's in there now, like instantiation, boxing/unboxing to primitive types etc

fniephaus commented 5 years ago

GraalVM already has other high-level components like TRegex for regular expressions, so I think it makes sense to add support for large integers, strings, etc. as well. Also because this might allow us to implement them in a PE-friendly way.

fniephaus commented 5 years ago

@chumer friendly ping

snazy commented 5 years ago

Out of curiosity, is there a corresponding "non-Python" ticket for general support of BigInteger and BigDecimal? For example, a JavaScript function like return argument + 1; called with BigInteger.ONE returns a string 11, not another integer 2.

fniephaus commented 5 years ago

@snazy not that I know of. If you think this is an interop bug with JS, maybe open an issue against Graal.js?

LifeIsStrange commented 3 years ago

https://github.com/oracle/graal/issues/2737