Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adopting GraalVM's support for BigInteger #7420

Merged
merged 29 commits into from
Aug 3, 2023
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
eb89979
Request BigInteger if exact precision is requested
JaroslavTulach Jul 28, 2023
681d7b2
Removing assert mangling. Use power of 3 to disalign with binary enco…
JaroslavTulach Jul 28, 2023
f20b569
EnsoBigInteger no longer extends Number
JaroslavTulach Jul 28, 2023
ad2bae5
No longer need to supress abstract export warning
JaroslavTulach Jul 28, 2023
5c358a5
Note in changelog
JaroslavTulach Jul 28, 2023
a435d7c
Spec for working with BigInteger in various polyglot form
JaroslavTulach Jul 28, 2023
6d77f54
Merge with develop
JaroslavTulach Jul 28, 2023
ca73109
Simple BigInteger interop with Java test
JaroslavTulach Jul 29, 2023
be6e3f6
Cached and uncached version of ToEnsoNumberNode
JaroslavTulach Jul 29, 2023
21ef3b3
Can multiply big integer with long
JaroslavTulach Jul 29, 2023
4f9d8ca
Convert to EnsoBigInteger on boundary
JaroslavTulach Jul 29, 2023
59f3d36
Check expected_value is the same for all implementations
JaroslavTulach Jul 31, 2023
a667393
CONVERT_TO_BIG_INT not a number
JaroslavTulach Jul 31, 2023
a164a1b
Returning back deleted doByte conversion
JaroslavTulach Aug 1, 2023
335f469
Avoid conversion of values with warnings
JaroslavTulach Aug 1, 2023
986d7a2
Nicer toString() for Warning
JaroslavTulach Aug 1, 2023
ec5ee2a
Avoid conversion of valid protocol values
JaroslavTulach Aug 2, 2023
881f93b
Only convert TruffleObject instances that fit into big integer
JaroslavTulach Aug 2, 2023
28ab2de
Merge remote-tracking branch 'origin/develop' into wip/jtulach/BigInt…
JaroslavTulach Aug 2, 2023
90a2c7e
Removing duplicataed 7176 line
JaroslavTulach Aug 2, 2023
8730f48
Prefer intrinsified shouldNotReachHere over regular IllegalStateExcep…
JaroslavTulach Aug 2, 2023
b61860f
Verify big integer is_a Integer
JaroslavTulach Aug 2, 2023
4e9dfda
Adding Radek's test
JaroslavTulach Aug 2, 2023
9439797
Use WarningsLibrary as a guard
JaroslavTulach Aug 2, 2023
79cc212
Verify behavior of _:Integer
JaroslavTulach Aug 2, 2023
be82551
Removing debris
JaroslavTulach Aug 3, 2023
20a4d5a
Merge branch 'develop' into wip/jtulach/BigInt_7213
mergify[bot] Aug 3, 2023
45b66d8
Merge branch 'develop' into wip/jtulach/BigInt_7213
mergify[bot] Aug 3, 2023
99c7293
Merge branch 'develop' into wip/jtulach/BigInt_7213
mergify[bot] Aug 3, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,7 @@
- [Cache dataflow errors][7193]
- [Add endpoint for downloading a project][7291]
- [Update to GraalVM 23.0.0][7176]
- [Using official BigInteger support][7420]
- [Allow users to give a project other than Upper_Snake_Case name][7397]

[3227]: https://github.com/enso-org/enso/pull/3227
Expand Down Expand Up @@ -1035,6 +1036,7 @@
[7176]: https://github.com/enso-org/enso/pull/7176
[7193]: https://github.com/enso-org/enso/pull/7193
[7291]: https://github.com/enso-org/enso/pull/7291
[7420]: https://github.com/enso-org/enso/pull/7420
[7397]: https://github.com/enso-org/enso/pull/7397

# Enso 2.0.0-alpha.18 (2021-10-12)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package org.enso.interpreter.node.callable;

import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.ReportPolymorphism;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.MaterializedFrame;
Expand All @@ -15,15 +17,20 @@
import com.oracle.truffle.api.profiles.ConditionProfile;
import org.enso.interpreter.node.BaseNode;
import org.enso.interpreter.node.callable.dispatch.IndirectInvokeFunctionNode;
import org.enso.interpreter.node.callable.resolver.*;
import org.enso.interpreter.node.callable.resolver.HostMethodCallNode;
import org.enso.interpreter.node.callable.resolver.MethodResolverNode;
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
import org.enso.interpreter.runtime.callable.argument.CallArgumentInfo;
import org.enso.interpreter.runtime.callable.function.Function;
import org.enso.interpreter.runtime.data.ArrayRope;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.*;
import org.enso.interpreter.runtime.error.DataflowError;
import org.enso.interpreter.runtime.error.PanicSentinel;
import org.enso.interpreter.runtime.error.Warning;
import org.enso.interpreter.runtime.error.WithWarnings;
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.state.State;

Expand Down Expand Up @@ -189,6 +196,45 @@ Object doPolyglot(
return hostMethodCallNode.execute(polyglotCallType, symbol.getName(), self, args);
}

@Specialization(
guards = {
"!methods.hasType(self)",
"!methods.hasSpecialDispatch(self)",
"getPolyglotCallType(self, symbol, interop) == CONVERT_TO_BIG_INT"
})
Object doConvertNumber(
MaterializedFrame frame,
State state,
UnresolvedSymbol symbol,
Object self,
Object[] arguments,
CallArgumentInfo[] schema,
InvokeCallableNode.DefaultsExecutionMode defaultsExecutionMode,
InvokeCallableNode.ArgumentsExecutionMode argumentsExecutionMode,
BaseNode.TailStatus isTail,
int thisArgumentPosition,
@Shared("typesLib") @CachedLibrary(limit = "10") TypesLibrary methods,
@Shared("interopLib") @CachedLibrary(limit = "10") InteropLibrary interop,
@Cached ToEnsoNumberNode toEnsoNumberNode) {
try {
var big = interop.asBigInteger(self);
var number = toEnsoNumberNode.execute(big);
return execute(
frame,
state,
symbol,
number,
arguments,
schema,
defaultsExecutionMode,
argumentsExecutionMode,
isTail,
thisArgumentPosition);
} catch (UnsupportedMessageException ex) {
throw CompilerDirectives.shouldNotReachHere(ex);
}
}

@Specialization(
guards = {
"!methods.hasType(self)",
Expand Down Expand Up @@ -226,8 +272,8 @@ Object doConvertText(
defaultsExecutionMode,
argumentsExecutionMode,
isTail);
} catch (UnsupportedMessageException e) {
throw new IllegalStateException("Impossible, self is guaranteed to be a string.");
} catch (UnsupportedMessageException ex) {
throw CompilerDirectives.shouldNotReachHere(ex);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,5 @@
package org.enso.interpreter.node.callable;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NonIdempotent;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.api.profiles.CountingConditionProfile;
import com.oracle.truffle.api.source.SourceSection;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.ZoneId;
Expand All @@ -26,7 +8,7 @@
import java.util.Objects;
import java.util.UUID;
import java.util.concurrent.locks.Lock;
import org.enso.interpreter.Constants;

import org.enso.interpreter.Constants.Names;
import org.enso.interpreter.node.BaseNode;
import org.enso.interpreter.node.MethodRootNode;
Expand All @@ -36,6 +18,7 @@
import org.enso.interpreter.node.callable.resolver.HostMethodCallNode;
import org.enso.interpreter.node.callable.resolver.MethodResolverNode;
import org.enso.interpreter.node.callable.thunk.ThunkExecutorNode;
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
import org.enso.interpreter.runtime.EnsoContext;
import org.enso.interpreter.runtime.builtin.Builtins;
import org.enso.interpreter.runtime.callable.UnresolvedSymbol;
Expand All @@ -60,6 +43,24 @@
import org.enso.interpreter.runtime.library.dispatch.TypesLibrary;
import org.enso.interpreter.runtime.state.State;

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.dsl.Bind;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NonIdempotent;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.ExplodeLoop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.profiles.BranchProfile;
import com.oracle.truffle.api.profiles.CountingConditionProfile;
import com.oracle.truffle.api.source.SourceSection;

@ImportStatic({HostMethodCallNode.PolyglotCallType.class, HostMethodCallNode.class})
public abstract class InvokeMethodNode extends BaseNode {
protected static final int CACHE_SIZE = 10;
Expand Down Expand Up @@ -393,8 +394,7 @@ Object doWarning(
selfWithoutWarnings = warnings.removeWarnings(self);
arrOfWarnings = warnings.getWarnings(self, this);
} catch (UnsupportedMessageException e) {
// Can't throw `CompilerDirectives.shouldNotReachHere` as it crashes native-image build
throw new IllegalStateException(e);
throw CompilerDirectives.shouldNotReachHere(e);
}

// Cannot use @Cached for childDispatch, because we need to call notifyInserted.
Expand Down Expand Up @@ -470,7 +470,7 @@ Object doPolyglot(
accumulatedWarnings = accumulatedWarnings.append(warnings.getWarnings(r, this));
args[i] = warnings.removeWarnings(r);
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
throw CompilerDirectives.shouldNotReachHere(e);
}
} else {
args[i] = r;
Expand All @@ -484,6 +484,34 @@ Object doPolyglot(
return res;
}

@Specialization(
guards = {
"!warnings.hasWarnings(self)",
"!types.hasType(self)",
"!types.hasSpecialDispatch(self)",
"getPolyglotCallType(self, symbol, interop) == CONVERT_TO_BIG_INT"
})
Object doConvertNumber(
VirtualFrame frame,
State state,
UnresolvedSymbol symbol,
Object self,
Object[] arguments,
@Shared("interop") @CachedLibrary(limit = "10") InteropLibrary interop,
@Shared("types") @CachedLibrary(limit = "10") TypesLibrary types,
@Shared("warnings") @CachedLibrary(limit = "10") WarningsLibrary warnings,
@Shared("methodResolverNode") @Cached MethodResolverNode methodResolverNode,
@Cached ToEnsoNumberNode toEnsoNumberNode) {
try {
var big = interop.asBigInteger(self);
var ensoBig = toEnsoNumberNode.execute(big);
arguments[0] = ensoBig;
return execute(frame, state, symbol, ensoBig, arguments);
} catch (UnsupportedMessageException e) {
throw CompilerDirectives.shouldNotReachHere(e);
}
}

@Specialization(
guards = {
"!warnings.hasWarnings(self)",
Expand All @@ -510,7 +538,7 @@ Object doConvertText(
arguments[0] = text;
return invokeFunctionNode.execute(function, frame, state, arguments);
} catch (UnsupportedMessageException e) {
throw new IllegalStateException("Impossible, self is guaranteed to be a string.");
throw CompilerDirectives.shouldNotReachHere(e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ public enum PolyglotCallType {
* org.enso.interpreter.runtime.data.text.Text} and dispatching natively.
*/
CONVERT_TO_TEXT,
/**
* The method call should be handled by converting {@code self} to a {@link EnsoBigInteger} and
* dispatching natively.
*/
CONVERT_TO_BIG_INT,
/**
* The method call should be handled by converting {@code self} dispatching natively to methods
* of {@link org.enso.interpreter.runtime.data.Array}
Expand Down Expand Up @@ -100,6 +105,7 @@ public boolean isInteropLibrary() {
return this != NOT_SUPPORTED
&& this != CONVERT_TO_ARRAY
&& this != CONVERT_TO_TEXT
&& this != CONVERT_TO_BIG_INT
&& this != CONVERT_TO_DATE
&& this != CONVERT_TO_DATE_TIME
&& this != CONVERT_TO_DURATION
Expand Down Expand Up @@ -159,6 +165,8 @@ public static PolyglotCallType getPolyglotCallType(
return PolyglotCallType.CONVERT_TO_DURATION;
} else if (library.isTimeZone(self)) {
return PolyglotCallType.CONVERT_TO_TIME_ZONE;
} else if (library.fitsInBigInteger(self)) {
return PolyglotCallType.CONVERT_TO_BIG_INT;
} else if (library.isString(self)) {
return PolyglotCallType.CONVERT_TO_TEXT;
} else if (library.hasArrayElements(self)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
package org.enso.interpreter.node.expression.builtin.interop.syntax;

import com.oracle.truffle.api.dsl.*;
import com.oracle.truffle.api.dsl.Cached;
import com.oracle.truffle.api.dsl.Cached.Shared;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateUncached;
import com.oracle.truffle.api.dsl.NeverDefault;
import com.oracle.truffle.api.dsl.ReportPolymorphism;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.interop.InteropLibrary;
import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.library.CachedLibrary;
import com.oracle.truffle.api.nodes.Node;
import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode;
import org.enso.interpreter.node.expression.foreign.CoerceNothing;
import org.enso.interpreter.runtime.data.text.Text;
import org.enso.interpreter.runtime.error.WarningsLibrary;
import org.enso.interpreter.runtime.error.WithWarnings;

/**
* Converts a value returned by a polyglot call back to a value that can be further used within Enso
Expand Down Expand Up @@ -56,15 +66,30 @@ long doChar(char i) {
return i;
}

@Specialization(guards = {"n != null", "iop.fitsInBigInteger(n)"})
Object doBigIntegerConversion(
TruffleObject n,
@Shared("iop") @CachedLibrary(limit = "3") InteropLibrary iop,
@Cached ToEnsoNumberNode to) {
try {
if (n instanceof WithWarnings) {
JaroslavTulach marked this conversation as resolved.
Show resolved Hide resolved
return n;
}
return to.execute(iop.asBigInteger(n));
} catch (UnsupportedMessageException e) {
throw new IllegalStateException(e);
}
}

@Specialization
Text doString(String txt) {
return Text.create(txt);
}

@Specialization(guards = {"o != null", "nulls.isNull(o)"})
@Specialization(guards = {"o != null", "iop.isNull(o)"})
Object doNull(
Object o,
@CachedLibrary(limit = "3") InteropLibrary nulls,
@Shared("iop") @CachedLibrary(limit = "3") InteropLibrary iop,
@CachedLibrary(limit = "3") WarningsLibrary warnings,
@Cached CoerceNothing coerceNothing) {
return coerceNothing.execute(o);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ boolean equalsDoubleBool(double self, boolean other) {
@Specialization
@TruffleBoundary
boolean equalsDoubleBigInt(double self, EnsoBigInteger other) {
return self == other.doubleValue();
return self == other.asDouble();
}

@Specialization
Expand All @@ -130,7 +130,7 @@ boolean equalsBigIntBigInt(EnsoBigInteger self, EnsoBigInteger otherBigInt) {
@Specialization
@TruffleBoundary
boolean equalsBitIntDouble(EnsoBigInteger self, double other) {
return self.doubleValue() == other;
return self.asDouble() == other;
}

@Specialization
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

@BuiltinMethod(type = "Big_Integer", name = "abs", description = "Big integer absolute value.")
public class AbsNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();

Object execute(EnsoBigInteger self) {
return toEnsoNumberNode.execute(BigIntegerOps.abs(self.getValue()));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@BuiltinMethod(type = "Big_Integer", name = "+", description = "Big integer addition.")
public abstract class AddNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();

abstract Object execute(EnsoBigInteger self, Object that);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@BuiltinMethod(type = "Big_Integer", name = "bit_and", description = "Bitwise and.")
public abstract class BitAndNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();

abstract Object execute(Object self, Object that);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@BuiltinMethod(type = "Big_Integer", name = "bit_or", description = "Bitwise or.")
public abstract class BitOrNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();

abstract Object execute(Object self, Object that);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
@ImportStatic(BigIntegerOps.class)
@BuiltinMethod(type = "Big_Integer", name = "bit_shift", description = "Bitwise shift.")
public abstract class BitShiftNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();
private final CountingConditionProfile fitsInIntProfileLeftShift =
CountingConditionProfile.create();
private final CountingConditionProfile fitsInIntProfileRightShift =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

@BuiltinMethod(type = "Big_Integer", name = "bit_xor", description = "Bitwise exclusive or.")
public abstract class BitXorNode extends Node {
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.build();
private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create();

abstract Object execute(EnsoBigInteger self, Object that);

Expand Down
Loading