diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java index d7db82bdc4b5..26526d47b077 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/AddNode.java @@ -1,10 +1,5 @@ package org.enso.interpreter.node.expression.builtin.number.integer; -import org.enso.interpreter.dsl.BuiltinMethod; -import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; -import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; -import org.enso.interpreter.runtime.number.EnsoBigInteger; - import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Fallback; @@ -14,6 +9,10 @@ import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node.Child; +import org.enso.interpreter.dsl.BuiltinMethod; +import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; +import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; +import org.enso.interpreter.runtime.number.EnsoBigInteger; @BuiltinMethod(type = "Integer", name = "+", description = "Addition of numbers.") public abstract class AddNode extends IntegerNode { diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java index b8ac1222cf87..7b03a8bf4ce7 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitNotNode.java @@ -3,7 +3,6 @@ import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.number.EnsoBigInteger; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java index 14b0f202bfe9..8a436f2a4df8 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/BitShiftRightNode.java @@ -4,7 +4,6 @@ import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.number.EnsoBigInteger; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java index cfd0ab6af420..d05b0654023d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/CeilNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.number.EnsoBigInteger; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java index f449f532a067..77f71d2f95f0 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/DivideNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.number.EnsoBigInteger; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java index 6c7ad5012bea..8f197dae3522 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/FloorNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.runtime.number.EnsoBigInteger; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java index 4fafb7060b0e..33ee6f96ed7d 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java index 2240179c16a9..fdf53dbea915 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/GreaterOrEqualNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerNode.java index 3f1ab586b7cf..f3444c6275c2 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/IntegerNode.java @@ -1,14 +1,13 @@ package org.enso.interpreter.node.expression.builtin.number.integer; -import org.enso.interpreter.runtime.EnsoContext; -import org.enso.interpreter.runtime.error.PanicException; -import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; -import org.enso.interpreter.runtime.number.EnsoBigInteger; - import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.nodes.Node; +import org.enso.interpreter.runtime.EnsoContext; +import org.enso.interpreter.runtime.error.PanicException; +import org.enso.interpreter.runtime.library.dispatch.TypesLibrary; +import org.enso.interpreter.runtime.number.EnsoBigInteger; abstract class IntegerNode extends Node { IntegerNode() {} diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java index 3bc1e78cc6e6..0dd150218b3c 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java index 71c29648f70b..779626c3d3b8 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/LessOrEqualNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.EnsoContext; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java index a632e59c1e0d..357ce002538b 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/PowNode.java @@ -3,16 +3,13 @@ import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; - +import com.oracle.truffle.api.nodes.Node.Child; import java.math.BigInteger; - import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; import org.enso.interpreter.runtime.number.EnsoBigInteger; -import com.oracle.truffle.api.nodes.Node.Child; - @BuiltinMethod(type = "Integer", name = "^", description = "Exponentiation of numbers.") public abstract class PowNode extends IntegerNode { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java index b10408d89288..0b0fa0d5fd89 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/RoundNode.java @@ -1,6 +1,5 @@ package org.enso.interpreter.node.expression.builtin.number.integer; -import com.oracle.truffle.api.nodes.Node.Child; import com.oracle.truffle.api.profiles.BranchProfile; import com.oracle.truffle.api.profiles.CountingConditionProfile; import com.oracle.truffle.api.profiles.PrimitiveValueProfile; diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java index e04cb3df35bf..acc69b735b76 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/SubtractNode.java @@ -2,14 +2,12 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; - +import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.node.expression.builtin.number.utils.ToEnsoNumberNode; import org.enso.interpreter.runtime.number.EnsoBigInteger; -import com.oracle.truffle.api.nodes.Node.Child; - @BuiltinMethod(type = "Integer", name = "-", description = "Subtraction of numbers.") public abstract class SubtractNode extends IntegerNode { private @Child ToEnsoNumberNode toEnsoNumberNode = ToEnsoNumberNode.create(); diff --git a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java index da8a504b644b..9660b3e69c79 100644 --- a/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java +++ b/engine/runtime/src/main/java/org/enso/interpreter/node/expression/builtin/number/integer/ToDecimalNode.java @@ -2,7 +2,6 @@ import com.oracle.truffle.api.dsl.Fallback; import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node.Child; import org.enso.interpreter.dsl.BuiltinMethod; import org.enso.interpreter.node.expression.builtin.number.utils.BigIntegerOps; import org.enso.interpreter.runtime.number.EnsoBigInteger; diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java index b7b8ebc82831..67477989c3f6 100644 --- a/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/EqualsTest.java @@ -199,130 +199,6 @@ public void testVectorsEquality() { }); } - @ExportLibrary(InteropLibrary.class) - static final class WrappedPrimitive implements TruffleObject { - private final Object value; - - WrappedPrimitive(long value) { - this.value = value; - } - - WrappedPrimitive(boolean value) { - this.value = value; - } - - WrappedPrimitive(double value) { - this.value = value; - } - - WrappedPrimitive(BigInteger value) { - this.value = value; - } - - WrappedPrimitive(String value) { - this.value = value; - } - - @ExportMessage - boolean isString() { - return value instanceof String; - } - - @ExportMessage - String asString() { - return (String) value; - } - - @ExportMessage - boolean isNumber() { - return value instanceof Number; - } - - @ExportMessage - boolean isBoolean() { - return value instanceof Boolean; - } - - @ExportMessage - boolean asBoolean() { - return (Boolean) value; - } - - @ExportMessage - boolean fitsInByte() { - return false; - } - - @ExportMessage - boolean fitsInShort() { - return false; - } - - @ExportMessage - boolean fitsInInt() { - return false; - } - - @ExportMessage - boolean fitsInLong() { - return value instanceof Long; - } - - @ExportMessage - boolean fitsInFloat() { - return false; - } - - @ExportMessage - boolean fitsInDouble() { - return value instanceof Double; - } - - @ExportMessage - byte asByte() throws UnsupportedMessageException { - throw UnsupportedMessageException.create(); - } - - @ExportMessage - short asShort() throws UnsupportedMessageException { - throw UnsupportedMessageException.create(); - } - - @ExportMessage - int asInt() throws UnsupportedMessageException { - throw UnsupportedMessageException.create(); - } - - @ExportMessage - long asLong() throws UnsupportedMessageException { - return (Long) value; - } - - @ExportMessage - float asFloat() throws UnsupportedMessageException { - throw UnsupportedMessageException.create(); - } - - @ExportMessage - double asDouble() throws UnsupportedMessageException { - return (Double) value; - } - - @ExportMessage - boolean fitsInBigInteger() { - return value instanceof BigInteger; - } - - @ExportMessage - BigInteger asBigInteger() throws UnsupportedMessageException { - return (BigInteger) value; - } - - Object asDirect() { - return value; - } - } - @Test public void testTruffleNumberLong() { var ensoNumber = unwrapValue(context, createValue(context, "1", "")); diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/NumbersTest.java b/engine/runtime/src/test/java/org/enso/interpreter/test/NumbersTest.java new file mode 100644 index 000000000000..64ffd29c0b02 --- /dev/null +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/NumbersTest.java @@ -0,0 +1,78 @@ +package org.enso.interpreter.test; + +import java.util.Random; + +import org.enso.polyglot.MethodNames; +import org.graalvm.polyglot.Context; +import org.junit.AfterClass; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import org.junit.BeforeClass; +import org.junit.experimental.theories.DataPoints; +import org.junit.experimental.theories.FromDataPoints; +import org.junit.experimental.theories.Theories; +import org.junit.experimental.theories.Theory; +import org.junit.runner.RunWith; + +@RunWith(Theories.class) +public class NumbersTest extends TestBase { + + @DataPoints("operation") + public static final String[] OPERATION = { + " +", " -", " ^", " *", " %", " <=", " <", " >=", " >", " /", + ".div", ".bit_xor", ".bit_shift", ".bit_shift_r", ".bit_or", ".bit_and" + }; + private static Context ctx; + + @BeforeClass + public static void initContext() { + ctx = createDefaultContext(); + } + + @AfterClass + public static void closeContext() { + ctx.close(); + } + + @Theory + public void verifyOperationOnForeignObject( + @FromDataPoints("operation") String operation + ) { + executeInContext(ctx, () -> { + var code = """ + fn a b = a{op} b + """.replace("{op}", operation); + var fn = ctx.eval("enso", code).invokeMember(MethodNames.Module.EVAL_EXPRESSION, "fn"); + + var r = new Random(); + var n1 = r.nextInt(); + var n2 = r.nextInt(); + System.out.println(n1 + operation + " " + n2); + + var r1 = fn.execute(n1, n2); + + var wrap2 = ctx.asValue(new WrappedPrimitive(n2)); + var r2 = fn.execute(n1, wrap2); + + assertEquals("r1: " + r1 + " r2: " + r2, r1.isBoolean(), r2.isBoolean()); + assertEquals("r1: " + r1 + " r2: " + r2, r1.fitsInLong(), r2.fitsInLong()); + assertEquals("r1: " + r1 + " r2: " + r2, r1.fitsInDouble(), r2.fitsInDouble()); + assertEquals("r1: " + r1 + " r2: " + r2, r1.fitsInBigInteger(), r2.fitsInBigInteger()); + + if (r1.fitsInLong()) { + assertEquals("Results for " + n1 + operation + " " + n2, r1.asLong(), r2.asLong()); + } else if (r1.fitsInDouble()) { + assertEquals("Results for " + n1 + operation + " " + n2, r1.asDouble(), r2.asDouble(), 0.1); + } else if (r1.fitsInBigInteger()) { + assertEquals("Results for " + n1 + operation + " " + n2, r1.asBigInteger(), r2.asBigInteger()); + } else if (r1.isBoolean()) { + assertEquals("Results for " + n1 + operation + " " + n2, r1.asBoolean(), r2.asBoolean()); + } else { + fail("Doesn't fit: " + r1); + } + + return null; + }); + } +} diff --git a/engine/runtime/src/test/java/org/enso/interpreter/test/WrappedPrimitive.java b/engine/runtime/src/test/java/org/enso/interpreter/test/WrappedPrimitive.java new file mode 100644 index 000000000000..0b102216fc90 --- /dev/null +++ b/engine/runtime/src/test/java/org/enso/interpreter/test/WrappedPrimitive.java @@ -0,0 +1,133 @@ +package org.enso.interpreter.test; + +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.ExportLibrary; +import com.oracle.truffle.api.library.ExportMessage; +import java.math.BigInteger; + +@ExportLibrary(InteropLibrary.class) +final class WrappedPrimitive implements TruffleObject { + + private final Object value; + + WrappedPrimitive(long value) { + this.value = value; + } + + WrappedPrimitive(boolean value) { + this.value = value; + } + + WrappedPrimitive(double value) { + this.value = value; + } + + WrappedPrimitive(BigInteger value) { + this.value = value; + } + + WrappedPrimitive(String value) { + this.value = value; + } + + @ExportMessage + boolean isString() { + return value instanceof String; + } + + @ExportMessage + String asString() { + return (String) value; + } + + @ExportMessage + boolean isNumber() { + return value instanceof Number; + } + + @ExportMessage + boolean isBoolean() { + return value instanceof Boolean; + } + + @ExportMessage + boolean asBoolean() { + return (Boolean) value; + } + + @ExportMessage + boolean fitsInByte() { + return false; + } + + @ExportMessage + boolean fitsInShort() { + return false; + } + + @ExportMessage + boolean fitsInInt() { + return false; + } + + @ExportMessage + boolean fitsInLong() { + return value instanceof Long; + } + + @ExportMessage + boolean fitsInFloat() { + return false; + } + + @ExportMessage + boolean fitsInDouble() { + return value instanceof Double; + } + + @ExportMessage + byte asByte() throws UnsupportedMessageException { + throw UnsupportedMessageException.create(); + } + + @ExportMessage + short asShort() throws UnsupportedMessageException { + throw UnsupportedMessageException.create(); + } + + @ExportMessage + int asInt() throws UnsupportedMessageException { + throw UnsupportedMessageException.create(); + } + + @ExportMessage + long asLong() throws UnsupportedMessageException { + return (Long) value; + } + + @ExportMessage + float asFloat() throws UnsupportedMessageException { + throw UnsupportedMessageException.create(); + } + + @ExportMessage + double asDouble() throws UnsupportedMessageException { + return (Double) value; + } + + @ExportMessage + boolean fitsInBigInteger() { + return value instanceof BigInteger; + } + + @ExportMessage + BigInteger asBigInteger() throws UnsupportedMessageException { + return (BigInteger) value; + } + + Object asDirect() { + return value; + } +}