diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 780e0edbf..41f87b1b7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -89,6 +89,22 @@ jobs: ./som -G -cp core-lib/Smalltalk:core-lib/TestSuite:core-lib/SomSom/src/compiler:core-lib/SomSom/src/vm:core-lib/SomSom/src/vmobjects:core-lib/SomSom/src/interpreter:core-lib/SomSom/src/primitives \ core-lib/SomSom/tests/SomSomTests.som + - name: Integration Tests + run: | + python -m pip install --upgrade pip + pip install pytest + + export CLASSPATH=Smalltalk + export AWFY=core-lib/Examples/AreWeFastYet/Core + + export TEST_EXPECTATIONS=./integration-tests-ast.yml + export VM="./som -G -Dsom.interp=AST" + pytest --tb=short core-lib/IntegrationTests + + export TEST_EXPECTATIONS=./integration-tests-bc.yml + export VM="./som -G -Dsom.interp=BC" + pytest --tb=short core-lib/IntegrationTests + - name: Checkout AWFY uses: actions/checkout@v4 with: diff --git a/core-lib b/core-lib index 7bf0413d9..a721b4ff6 160000 --- a/core-lib +++ b/core-lib @@ -1 +1 @@ -Subproject commit 7bf0413d9e90e0484f5bde24f44b654c3672da24 +Subproject commit a721b4ff6ecb1ade54e0afe0bd15a8e80e41af17 diff --git a/integration-tests-ast.yml b/integration-tests-ast.yml new file mode 100644 index 000000000..820612633 --- /dev/null +++ b/integration-tests-ast.yml @@ -0,0 +1,143 @@ +known_failures: [] + + +failing_as_unspecified: + - Tests/arbint_double_div_err.som + - Tests/arbint_double_div_zero_err.som + - Tests/arbint_modulus_err.som + - Tests/array_at_idx0_err.som + - Tests/array_at_idx2_err.som + - Tests/array_at_idx_err.som + - Tests/array_at_negative_idx_err.som + - Tests/array_at_put_idx0_err.som + - Tests/array_at_put_idx2_err.som + - Tests/call2.som + + # I think this one is about E vs e, but maybe also double rendering + - Tests/double2.som + - Tests/double_double_div.som + - Tests/int_double_div.som + # - Tests/integer_asdouble.som + - Tests/int26.som + + # I think IEEE allows for infinities here, and we probably want that + - Tests/double3.som + - Tests/double4.som + - Tests/double5.som + - Tests/double6.som + - Tests/double7.som + - Tests/double8.som + - Tests/double9.som + - Tests/double11.som + - Tests/double13.som + + # Java seems to do some rounding in the transition, but it's also requiring bigints + - Tests/double_asinteger.som + + + - Tests/double_double_div_err.som + - Tests/double_double_div_zero_err1.som + - Tests/double_double_div_zero_err2.som + - Tests/double_double_div_zero_err3.som + - Tests/double_double_div_zero_err4.som + - Tests/double_modulus.som + - Tests/double_modulus_err.som + + - Tests/exit_double.som + - Tests/exit_int_too_big.som + - Tests/exit_string.som + + - Tests/fromstring_double_err.som + - Tests/fromstring_err.som + + - Tests/hashcode2.som + + - Tests/inst_var_at_bad_idx.som + - Tests/inst_var_at_put_bad_idx.som + + - Tests/instance_fields_overlap/test.som + - Tests/instance_fields_overlap2.som + + - Tests/int5.som + - Tests/int8.som + - Tests/int9.som + + - Tests/int10.som + - Tests/int11.som + - Tests/int12.som + - Tests/int13.som + - Tests/int14.som + - Tests/int15.som + - Tests/int16.som + - Tests/int17.som + + # too large shifts would take too much memory to support + # need to specify this some how + - Tests/int20.som + - Tests/int21.som + - Tests/int22.som + - Tests/int23.som + - Tests/int25.som + - Tests/int27.som + - Tests/int28.som + - Tests/int31.som + + # return type of sqrt + - Tests/int29.som + + - Tests/int_double_div_err.som + - Tests/int_double_div_zero_err.som + - Tests/int_modulus.som + - Tests/int_modulus_err.som + + - Tests/load_string.som + + - Tests/mutate_fields.som + - Tests/mutate_methods.som + - Tests/mutate_superclass_method/test.som + + - Tests/nested_backtrace1.som + - Tests/nested_backtrace2.som + + - Tests/obj2.som + + - Tests/perform_string.som + - Tests/perform_witharguments_wrong.som + + # - Tests/positive_infinity.som + + - Tests/remainder_zero.som + - Tests/round.som + + - Tests/shift_right.som + - Tests/shift_right_too_big.som + - Tests/shift_right_type_err.som + + - Tests/str_escape_unknown.som + + - Tests/system2.som + - Tests/system_global_lookup_string.som + - Tests/system_global_put_string.som + + - Tests/test_literals_limit_1.som + - Tests/test_literals_limit_2.som + - Tests/unknown_field_write.som + + # methods array should be specified as being unstable + - Tests/hashcode.som + + # specify true, false, nil as literals, not globals + - Tests/system_global.som + + +unsupported: + # to be implemented + - Tests/binary_super.som + - Tests/bool4.som + - Tests/bool5.som + + # just broken + - Tests/perform_in_superclass_with_args.som + + +do_not_run: [] diff --git a/integration-tests-bc.yml b/integration-tests-bc.yml new file mode 100644 index 000000000..06112fc2c --- /dev/null +++ b/integration-tests-bc.yml @@ -0,0 +1,146 @@ +known_failures: [] + + +failing_as_unspecified: + - Tests/arbint_double_div_err.som + - Tests/arbint_double_div_zero_err.som + - Tests/arbint_modulus_err.som + - Tests/array_at_idx0_err.som + - Tests/array_at_idx2_err.som + - Tests/array_at_idx_err.som + - Tests/array_at_negative_idx_err.som + - Tests/array_at_put_idx0_err.som + - Tests/array_at_put_idx2_err.som + - Tests/call2.som + + # I think this one is about E vs e, but maybe also double rendering + - Tests/double2.som + - Tests/double_double_div.som + - Tests/int_double_div.som + # - Tests/integer_asdouble.som + - Tests/int26.som + + # I think IEEE allows for infinities here, and we probably want that + - Tests/double3.som + - Tests/double4.som + - Tests/double5.som + - Tests/double6.som + - Tests/double7.som + - Tests/double8.som + - Tests/double9.som + - Tests/double11.som + - Tests/double13.som + + # Java seems to do some rounding in the transition, but it's also requiring bigints + - Tests/double_asinteger.som + + + - Tests/double_double_div_err.som + - Tests/double_double_div_zero_err1.som + - Tests/double_double_div_zero_err2.som + - Tests/double_double_div_zero_err3.som + - Tests/double_double_div_zero_err4.som + - Tests/double_modulus.som + - Tests/double_modulus_err.som + + - Tests/exit_double.som + - Tests/exit_int_too_big.som + - Tests/exit_string.som + + - Tests/fromstring_double_err.som + - Tests/fromstring_err.som + + - Tests/hashcode2.som + + - Tests/inst_var_at_bad_idx.som + - Tests/inst_var_at_put_bad_idx.som + + - Tests/instance_fields_overlap/test.som + - Tests/instance_fields_overlap2.som + + - Tests/int5.som + - Tests/int8.som + - Tests/int9.som + + - Tests/int10.som + - Tests/int11.som + - Tests/int12.som + - Tests/int13.som + - Tests/int14.som + - Tests/int15.som + - Tests/int16.som + - Tests/int17.som + + # too large shifts would take too much memory to support + # need to specify this some how + - Tests/int20.som + - Tests/int21.som + - Tests/int22.som + - Tests/int23.som + - Tests/int25.som + - Tests/int27.som + - Tests/int28.som + - Tests/int31.som + + # return type of sqrt + - Tests/int29.som + + - Tests/int_double_div_err.som + - Tests/int_double_div_zero_err.som + - Tests/int_modulus.som + - Tests/int_modulus_err.som + + - Tests/load_string.som + + - Tests/mutate_fields.som + - Tests/mutate_methods.som + - Tests/mutate_superclass_method/test.som + + - Tests/nested_backtrace1.som + - Tests/nested_backtrace2.som + + - Tests/obj2.som + + - Tests/perform_string.som + - Tests/perform_witharguments_wrong.som + + # - Tests/positive_infinity.som + + - Tests/remainder_zero.som + - Tests/round.som + + - Tests/shift_right.som + - Tests/shift_right_too_big.som + - Tests/shift_right_type_err.som + + - Tests/str_escape_unknown.som + + - Tests/system2.som + - Tests/system_global_lookup_string.som + - Tests/system_global_put_string.som + + - Tests/test_literals_limit_1.som + - Tests/test_literals_limit_2.som + - Tests/unknown_field_write.som + + # methods array should be specified as being unstable + - Tests/hashcode.som + + # specify true, false, nil as literals, not globals + - Tests/system_global.som + + +unsupported: + # to be implemented + - Tests/binary_super.som + - Tests/binary_super/test.som + # - Tests/bool4.som + # - Tests/bool5.som + + # just broken + - Tests/perform_in_superclass_with_args.som + + - Tests/int4.som + - Tests/to32bits.som + +do_not_run: [] diff --git a/src/trufflesom/src/trufflesom/primitives/arithmetic/BitXorPrim.java b/src/trufflesom/src/trufflesom/primitives/arithmetic/BitXorPrim.java index f96298f29..51b9207bb 100644 --- a/src/trufflesom/src/trufflesom/primitives/arithmetic/BitXorPrim.java +++ b/src/trufflesom/src/trufflesom/primitives/arithmetic/BitXorPrim.java @@ -1,5 +1,6 @@ package trufflesom.primitives.arithmetic; +import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.Specialization; @@ -7,6 +8,8 @@ import trufflesom.vm.SymbolTable; import trufflesom.vmobjects.SSymbol; +import java.math.BigInteger; + @GenerateNodeFactory @Primitive(className = "Integer", primitive = "bitXor:", selector = "bitXor:") @@ -16,6 +19,24 @@ public static final long doLong(final long receiver, final long right) { return receiver ^ right; } + @Specialization + @TruffleBoundary + public static final BigInteger doBigInt(final BigInteger receiver, final long right) { + return receiver.xor(BigInteger.valueOf(right)); + } + + @Specialization + @TruffleBoundary + public static final BigInteger doBigInt(final BigInteger receiver, final BigInteger right) { + return receiver.xor(right); + } + + @Specialization + @TruffleBoundary + public static final BigInteger doLong(final long receiver, final BigInteger right) { + return BigInteger.valueOf(receiver).xor(right); + } + @Override public final SSymbol getSelector() { return SymbolTable.symbolFor("bitXor:"); diff --git a/src/trufflesom/src/trufflesom/primitives/arithmetic/GreaterThanOrEqualPrim.java b/src/trufflesom/src/trufflesom/primitives/arithmetic/GreaterThanOrEqualPrim.java index 31df44a21..1143966b5 100644 --- a/src/trufflesom/src/trufflesom/primitives/arithmetic/GreaterThanOrEqualPrim.java +++ b/src/trufflesom/src/trufflesom/primitives/arithmetic/GreaterThanOrEqualPrim.java @@ -34,12 +34,12 @@ public static final boolean doLong(final long left, final BigInteger right) { @Specialization public static final boolean doLong(final long left, final double right) { - return doDouble(left, right); + return left >= right; } @Specialization public static final boolean doDouble(final double left, final long right) { - return doDouble(left, right); + return left >= right; } @Specialization diff --git a/src/trufflesom/src/trufflesom/primitives/arithmetic/LessThanOrEqualPrim.java b/src/trufflesom/src/trufflesom/primitives/arithmetic/LessThanOrEqualPrim.java index 821653881..d7a4b1dd0 100644 --- a/src/trufflesom/src/trufflesom/primitives/arithmetic/LessThanOrEqualPrim.java +++ b/src/trufflesom/src/trufflesom/primitives/arithmetic/LessThanOrEqualPrim.java @@ -28,7 +28,7 @@ public static final boolean doLong(final long left, final long right) { @Specialization public static final boolean doLong(final long left, final double right) { - return doDouble(left, right); + return left <= right; } @Specialization @@ -56,6 +56,6 @@ public static final boolean doDouble(final double left, final double right) { @Specialization public static final boolean doDouble(final double left, final long right) { - return doDouble(left, right); + return left <= right; } } diff --git a/src/trufflesom/src/trufflesom/primitives/arrays/AtPutPrim.java b/src/trufflesom/src/trufflesom/primitives/arrays/AtPutPrim.java index 36e05df37..45e179931 100644 --- a/src/trufflesom/src/trufflesom/primitives/arrays/AtPutPrim.java +++ b/src/trufflesom/src/trufflesom/primitives/arrays/AtPutPrim.java @@ -44,14 +44,14 @@ protected static final boolean valueNotLongDoubleBoolean(final Object value) { } @Specialization(guards = {"receiver.isEmptyType()"}) - public static final long doEmptySArray(final SArray receiver, final long index, + public static final Object doEmptySArray(final SArray receiver, final long index, final long value) { long idx = index - 1; assert idx >= 0; assert idx < receiver.getEmptyStorage(); receiver.transitionFromEmptyToPartiallyEmptyWith(idx, value); - return value; + return receiver; } @Specialization(guards = {"receiver.isEmptyType()"}) @@ -62,7 +62,7 @@ public static final Object doEmptySArray(final SArray receiver, final long index assert idx < receiver.getEmptyStorage(); receiver.transitionFromEmptyToPartiallyEmptyWith(idx, value); - return value; + return receiver; } @Specialization(guards = {"receiver.isEmptyType()"}) @@ -73,7 +73,7 @@ public static final Object doEmptySArray(final SArray receiver, final long index assert idx < receiver.getEmptyStorage(); receiver.transitionFromEmptyToPartiallyEmptyWith(idx, value); - return value; + return receiver; } @Specialization(guards = {"receiver.isEmptyType()", "valueIsNotNil(value)", @@ -91,7 +91,7 @@ public static final Object doEmptySArray(final SArray receiver, final long index newStorage[idx] = value; receiver.transitionTo(newStorage); - return value; + return receiver; } @Specialization(guards = {"receiver.isEmptyType()", "valueIsNil(value)"}) @@ -100,7 +100,7 @@ public static final Object doEmptySArrayWithNil(final SArray receiver, final lon long idx = index - 1; assert idx >= 0; assert idx < receiver.getEmptyStorage(); - return value; + return receiver; } private static void setValue(final long idx, final Object value, @@ -115,24 +115,24 @@ private static void setValue(final long idx, final Object value, } @Specialization(guards = "receiver.isPartiallyEmptyType()") - public static final long doPartiallyEmptySArray(final SArray receiver, + public static final Object doPartiallyEmptySArray(final SArray receiver, final long index, final long value) { setAndPossiblyTransition(receiver, index, value, PartiallyEmptyArray.Type.LONG); - return value; + return receiver; } @Specialization(guards = "receiver.isPartiallyEmptyType()") - public static final double doPartiallyEmptySArray(final SArray receiver, + public static final Object doPartiallyEmptySArray(final SArray receiver, final long index, final double value) { setAndPossiblyTransition(receiver, index, value, PartiallyEmptyArray.Type.DOUBLE); - return value; + return receiver; } @Specialization(guards = "receiver.isPartiallyEmptyType()") - public static final boolean doPartiallyEmptySArray(final SArray receiver, + public static final Object doPartiallyEmptySArray(final SArray receiver, final long index, final boolean value) { setAndPossiblyTransition(receiver, index, value, PartiallyEmptyArray.Type.BOOLEAN); - return value; + return receiver; } @Specialization(guards = {"receiver.isPartiallyEmptyType()", "valueIsNil(value)"}) @@ -147,14 +147,14 @@ public static final Object doPartiallyEmptySArrayWithNil(final SArray receiver, storage.incEmptyElements(); storage.set(idx, Nil.nilObject); } - return value; + return receiver; } @Specialization(guards = {"receiver.isPartiallyEmptyType()", "valueIsNotNil(value)"}) public static final Object doPartiallyEmptySArray(final SArray receiver, final long index, final Object value) { setAndPossiblyTransition(receiver, index, value, PartiallyEmptyArray.Type.OBJECT); - return value; + return receiver; } @Specialization(guards = "receiver.isObjectType()") @@ -162,7 +162,7 @@ public static final Object doObjectSArray(final SArray receiver, final long inde final Object value) { long idx = index - 1; receiver.getObjectStorage()[(int) idx] = value; - return value; + return receiver; } @Specialization(guards = "receiver.isLongType()") @@ -170,7 +170,7 @@ public static final Object doObjectSArray(final SArray receiver, final long inde final long value) { long idx = index - 1; receiver.getLongStorage()[(int) idx] = value; - return value; + return receiver; } @Specialization(guards = {"receiver.isLongType()", "valueIsNotLong(value)"}) @@ -190,7 +190,7 @@ public static final Object doDoubleSArray(final SArray receiver, final long inde final double value) { long idx = index - 1; receiver.getDoubleStorage()[(int) idx] = value; - return value; + return receiver; } @Specialization(guards = {"receiver.isDoubleType()", "valueIsNotDouble(value)"}) @@ -210,7 +210,7 @@ public static final Object doBooleanSArray(final SArray receiver, final long ind final boolean value) { long idx = index - 1; receiver.getBooleanStorage()[(int) idx] = value; - return value; + return receiver; } @Specialization(guards = {"receiver.isBooleanType()", "valueIsNotBoolean(value)"}) @@ -231,7 +231,7 @@ private static Object transitionAndSet(final SArray receiver, final long index, long idx = index - 1; receiver.transitionTo(newStorage); newStorage[(int) idx] = value; - return value; + return receiver; } private static void setAndPossiblyTransition(final SArray receiver, diff --git a/src/trufflesom/src/trufflesom/primitives/basics/EqualsPrim.java b/src/trufflesom/src/trufflesom/primitives/basics/EqualsPrim.java index e66be1c47..44a4e3ba3 100644 --- a/src/trufflesom/src/trufflesom/primitives/basics/EqualsPrim.java +++ b/src/trufflesom/src/trufflesom/primitives/basics/EqualsPrim.java @@ -69,6 +69,12 @@ public static final boolean doLong(final long left, final SSymbol right) { return false; } + @Specialization + @SuppressWarnings("unused") + public static final boolean doBigInt(final BigInteger left, final String right) { + return false; + } + @Specialization @TruffleBoundary public static final boolean doBigInteger(final BigInteger left, final long right) { diff --git a/src/trufflesom/src/trufflesom/primitives/basics/IntegerPrims.java b/src/trufflesom/src/trufflesom/primitives/basics/IntegerPrims.java index 510143e30..6ece2df2a 100644 --- a/src/trufflesom/src/trufflesom/primitives/basics/IntegerPrims.java +++ b/src/trufflesom/src/trufflesom/primitives/basics/IntegerPrims.java @@ -156,6 +156,15 @@ public static final BigInteger doLongWithOverflow(final long receiver, final lon return BigInteger.valueOf(receiver).shiftLeft((int) right); } + + @Specialization + @TruffleBoundary + public static final BigInteger doBigInt(final BigInteger receiver, final long right) { + assert right >= 0; // currently not defined for negative values of right + assert right <= Integer.MAX_VALUE; + + return receiver.shiftLeft((int) right); + } } @GenerateNodeFactory diff --git a/src/trufflesom/src/trufflesom/primitives/basics/SystemPrims.java b/src/trufflesom/src/trufflesom/primitives/basics/SystemPrims.java index 7a305b8ef..2ee080cdd 100644 --- a/src/trufflesom/src/trufflesom/primitives/basics/SystemPrims.java +++ b/src/trufflesom/src/trufflesom/primitives/basics/SystemPrims.java @@ -70,7 +70,7 @@ public static final Object doSObject(@SuppressWarnings("unused") final SObject r final SSymbol global, final Object value) { Globals.setGlobal(global, value); - return value; + return receiver; } } diff --git a/src/trufflesom/src/trufflesom/primitives/reflection/ObjectPrims.java b/src/trufflesom/src/trufflesom/primitives/reflection/ObjectPrims.java index c1d91037a..3044e2842 100644 --- a/src/trufflesom/src/trufflesom/primitives/reflection/ObjectPrims.java +++ b/src/trufflesom/src/trufflesom/primitives/reflection/ObjectPrims.java @@ -71,7 +71,7 @@ public abstract static class InstVarAtPutPrim extends TernaryExpressionNode { @Specialization public final Object doSObject(final SObject receiver, final long idx, final Object val) { dispatch.executeDispatch(receiver, (int) idx - 1, val); - return val; + return receiver; } @Override